merge with 3.21.3
authorRémi Cardona <remi.cardona@logilab.fr>
Thu, 10 Dec 2015 12:34:15 +0100
changeset 10960 9e64fddebc89
parent 10956 208c9ac8edbb (diff)
parent 10959 068dd72272f4 (current diff)
child 10961 6ff786884aad
merge with 3.21.3 The change in unittest_serverctl.py is needed because of daef7ce08fea (from 3.20.11) and 3914388b2d0f (from the 3.22 branch). Due to both changes, CubicWebTC.config.repository no longer creates a new repository (and thus, a new connection). Since both DBDumpCommand and CubicWebTC.tearDown try to shutdown the repo, tearDown breaks apart. The solution is to temporarily disable ServerConfiguration's config cache. By forcing DBDumpCommand to get a new configuration object, it then gets its own Repo object, allowing tearDown and DBDumpCommand to work independently.
cubicweb.spec
devtools/__init__.py
devtools/test/unittest_testlib.py
ext/rest.py
ext/test/unittest_rest.py
server/test/unittest_serverctl.py
--- a/__init__.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/__init__.py	Thu Dec 10 12:34:15 2015 +0100
@@ -22,23 +22,21 @@
 
 # ignore the pygments UserWarnings
 import warnings
-import cPickle
 import zlib
 warnings.filterwarnings('ignore', category=UserWarning,
                         message='.*was already imported',
                         module='.*pygments')
 
 
-import __builtin__
-# '_' is available in builtins to mark internationalized string but should
-# not be used to do the actual translation
-if not hasattr(__builtin__, '_'):
-    __builtin__._ = unicode
+from six import PY2, binary_type, text_type
+from six.moves import builtins
 
 CW_SOFTWARE_ROOT = __path__[0]
 
 import sys, os, logging
-from StringIO import StringIO
+from io import BytesIO
+
+from six.moves import cPickle as pickle
 
 from logilab.common.deprecation import deprecated
 from logilab.common.logging_ext import set_log_methods
@@ -56,6 +54,14 @@
 from cubicweb._exceptions import *
 from logilab.common.registry import ObjectNotFound, NoSelectableObject, RegistryNotFound
 
+
+# '_' is available to mark internationalized string but should not be used to
+# do the actual translation
+_ = text_type
+if not hasattr(builtins, '_'):
+    builtins._ = deprecated("[3.22] Use 'from cubicweb import _'")(_)
+
+
 # convert eid to the right type, raise ValueError if it's not a valid eid
 @deprecated('[3.17] typed_eid() was removed. replace it with int() when needed.')
 def typed_eid(eid):
@@ -66,17 +72,19 @@
 #import threading
 #threading.settrace(log_thread)
 
-class Binary(StringIO):
-    """customize StringIO to make sure we don't use unicode"""
-    def __init__(self, buf=''):
-        assert isinstance(buf, (str, buffer, bytearray)), \
-               "Binary objects must use raw strings, not %s" % buf.__class__
-        StringIO.__init__(self, buf)
+class Binary(BytesIO):
+    """class to hold binary data. Use BytesIO to prevent use of unicode data"""
+    _allowed_types = (binary_type, bytearray, buffer if PY2 else memoryview)
+
+    def __init__(self, buf=b''):
+        assert isinstance(buf, self._allowed_types), \
+               "Binary objects must use bytes/buffer objects, not %s" % buf.__class__
+        super(Binary, self).__init__(buf)
 
     def write(self, data):
-        assert isinstance(data, (str, buffer, bytearray)), \
-               "Binary objects must use raw strings, not %s" % data.__class__
-        StringIO.write(self, data)
+        assert isinstance(data, self._allowed_types), \
+               "Binary objects must use bytes/buffer objects, not %s" % data.__class__
+        super(Binary, self).write(data)
 
     def to_file(self, fobj):
         """write a binary to disk
@@ -132,22 +140,22 @@
     def zpickle(cls, obj):
         """ return a Binary containing a gzipped pickle of obj """
         retval = cls()
-        retval.write(zlib.compress(cPickle.dumps(obj, protocol=2)))
+        retval.write(zlib.compress(pickle.dumps(obj, protocol=2)))
         return retval
 
     def unzpickle(self):
         """ decompress and loads the stream before returning it """
-        return cPickle.loads(zlib.decompress(self.getvalue()))
+        return pickle.loads(zlib.decompress(self.getvalue()))
 
 
 def check_password(eschema, value):
-    return isinstance(value, (str, Binary))
+    return isinstance(value, (binary_type, Binary))
 BASE_CHECKERS['Password'] = check_password
 
 def str_or_binary(value):
     if isinstance(value, Binary):
         return value
-    return str(value)
+    return binary_type(value)
 BASE_CONVERTERS['Password'] = str_or_binary
 
 
@@ -255,4 +263,3 @@
     not be processed, a memory allocation error occurred during processing,
     etc.
     """
-
--- a/__pkginfo__.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/__pkginfo__.py	Thu Dec 10 12:34:15 2015 +0100
@@ -22,8 +22,8 @@
 
 modname = distname = "cubicweb"
 
-numversion = (3, 21, 3)
-version = '.'.join(str(num) for num in numversion)
+numversion = (3, 21, 99)
+version = '.'.join(str(num) for num in numversion) + '.dev0'
 
 description = "a repository of entities / relations for knowledge management"
 author = "Logilab"
@@ -39,10 +39,11 @@
 ]
 
 __depends__ = {
+    'six': '>= 1.4.0',
     'logilab-common': '>= 0.63.1',
     'logilab-mtconverter': '>= 0.8.0',
     'rql': '>= 0.31.2',
-    'yams': '>= 0.40.0',
+    'yams': '>= 0.41.1',
     #gettext                    # for xgettext, msgcat, etc...
     # web dependencies
     'lxml': '',
--- a/_exceptions.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/_exceptions.py	Thu Dec 10 12:34:15 2015 +0100
@@ -21,6 +21,8 @@
 
 from warnings import warn
 
+from six import PY3, text_type
+
 from logilab.common.decorators import cachedproperty
 
 from yams import ValidationError
@@ -30,23 +32,24 @@
 class CubicWebException(Exception):
     """base class for cubicweb server exception"""
     msg = ""
-    def __str__(self):
+    def __unicode__(self):
         if self.msg:
             if self.args:
                 return self.msg % tuple(self.args)
             else:
                 return self.msg
         else:
-            return u' '.join(unicode(arg) for arg in self.args)
+            return u' '.join(text_type(arg) for arg in self.args)
+    __str__ = __unicode__ if PY3 else lambda self: self.__unicode__().encode('utf-8')
 
 class ConfigurationError(CubicWebException):
     """a misconfiguration error"""
 
 class InternalError(CubicWebException):
-    """base class for exceptions which should not occurs"""
+    """base class for exceptions which should not occur"""
 
 class SecurityError(CubicWebException):
-    """base class for cubicweb server security exception"""
+    """base class for cubicweb server security exceptions"""
 
 class RepositoryError(CubicWebException):
     """base class for repository exceptions"""
@@ -185,7 +188,7 @@
          commit time.
 
     :type txuuix: int
-    :param txuuid: Unique identifier of the partialy undone transaction
+    :param txuuid: Unique identifier of the partially undone transaction
 
     :type errors: list
     :param errors: List of errors occurred during undoing
@@ -204,4 +207,3 @@
 
 # pylint: disable=W0611
 from logilab.common.clcommands import BadCommandUsage
-
--- a/_gcdebug.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/_gcdebug.py	Thu Dec 10 12:34:15 2015 +0100
@@ -15,6 +15,7 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
+from __future__ import print_function
 
 import gc, types, weakref
 
@@ -68,7 +69,7 @@
             except KeyError:
                 ocounters[key] = 1
         if isinstance(obj, viewreferrersclasses):
-            print '   ', obj, referrers(obj, showobjs, maxlevel)
+            print('   ', obj, referrers(obj, showobjs, maxlevel))
     garbage = [repr(obj) for obj in gc.garbage]
     return counters, ocounters, garbage
 
--- a/crypto.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/crypto.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,9 +18,10 @@
 """Simple cryptographic routines, based on python-crypto."""
 __docformat__ = "restructuredtext en"
 
-from pickle import dumps, loads
 from base64 import b64encode, b64decode
 
+from six.moves import cPickle as pickle
+
 from Crypto.Cipher import Blowfish
 
 
@@ -34,7 +35,7 @@
 
 
 def encrypt(data, seed):
-    string = dumps(data)
+    string = pickle.dumps(data)
     string = string + '*' * (8 - len(string) % 8)
     string = b64encode(_cypherer(seed).encrypt(string))
     return unicode(string)
@@ -43,4 +44,4 @@
 def decrypt(string, seed):
     # pickle ignores trailing characters so we do not need to strip them off
     string = _cypherer(seed).decrypt(b64decode(string))
-    return loads(string)
+    return pickle.loads(string)
--- a/cubicweb.spec	Wed Dec 09 18:42:13 2015 +0100
+++ b/cubicweb.spec	Thu Dec 10 12:34:15 2015 +0100
@@ -20,10 +20,11 @@
 BuildArch:      noarch
 
 Requires:       %{python}
+Requires:       %{python}-six >= 1.4.0
 Requires:       %{python}-logilab-common >= 0.63.1
 Requires:       %{python}-logilab-mtconverter >= 0.8.0
 Requires:       %{python}-rql >= 0.31.2
-Requires:       %{python}-yams >= 0.40.0
+Requires:       %{python}-yams >= 0.41.1
 Requires:       %{python}-logilab-database >= 1.13.0
 Requires:       %{python}-passlib
 Requires:       %{python}-lxml
--- a/cwconfig.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/cwconfig.py	Thu Dec 10 12:34:15 2015 +0100
@@ -164,9 +164,9 @@
 
    Directory where pid files will be written
 """
+from __future__ import print_function
 
 __docformat__ = "restructuredtext en"
-_ = unicode
 
 import sys
 import os
@@ -179,6 +179,8 @@
                      basename, isdir, dirname, splitext)
 from warnings import warn, filterwarnings
 
+from six import text_type
+
 from logilab.common.decorators import cached, classproperty
 from logilab.common.deprecation import deprecated
 from logilab.common.logging_ext import set_log_methods, init_log
@@ -186,7 +188,7 @@
                                           ConfigurationMixIn, merge_options)
 
 from cubicweb import (CW_SOFTWARE_ROOT, CW_MIGRATION_MAP,
-                      ConfigurationError, Binary)
+                      ConfigurationError, Binary, _)
 from cubicweb.toolsutils import create_dir
 
 CONFIGURATIONS = []
@@ -350,7 +352,7 @@
           }),
         ('umask',
          {'type' : 'int',
-          'default': 077,
+          'default': 0o077,
           'help': 'permission umask for files created by the server',
           'group': 'main', 'level': 2,
           }),
@@ -503,7 +505,7 @@
                 deps = {}
             else:
                 deps = dict( (x[len('cubicweb-'):], v)
-                             for x, v in gendeps.iteritems()
+                             for x, v in gendeps.items()
                              if x.startswith('cubicweb-'))
         for depcube in deps:
             try:
@@ -650,7 +652,7 @@
         self.adjust_sys_path()
         self.load_defaults()
         # will be properly initialized later by _gettext_init
-        self.translations = {'en': (unicode, lambda ctx, msgid: unicode(msgid) )}
+        self.translations = {'en': (text_type, lambda ctx, msgid: text_type(msgid) )}
         self._site_loaded = set()
         # don't register ReStructured Text directives by simple import, avoid pb
         # with eg sphinx.
@@ -960,7 +962,7 @@
             i = 1
             while exists(path) and i < 100: # arbitrary limit to avoid infinite loop
                 try:
-                    file(path, 'a')
+                    open(path, 'a')
                     break
                 except IOError:
                     path = '%s-%s.log' % (basepath, i)
@@ -994,6 +996,13 @@
         rtdir = abspath(os.environ.get('CW_RUNTIME_DIR', default))
         return join(rtdir, '%s-%s.pid' % (self.appid, self.name))
 
+    # config -> repository
+
+    def repository(self, vreg=None):
+        from cubicweb.server.repository import Repository
+        from cubicweb.server.utils import TasksManager
+        return Repository(self, TasksManager(), vreg=vreg)
+
     # instance methods used to get instance specific resources #############
 
     def __init__(self, appid, debugmode=False, creating=False):
@@ -1001,7 +1010,7 @@
         # set to true while creating an instance
         self.creating = creating
         super(CubicWebConfiguration, self).__init__(debugmode)
-        fake_gettext = (unicode, lambda ctx, msgid: unicode(msgid))
+        fake_gettext = (text_type, lambda ctx, msgid: text_type(msgid))
         for lang in self.available_languages():
             self.translations[lang] = fake_gettext
         self._cubes = None
@@ -1050,7 +1059,8 @@
 
     def save(self):
         """write down current configuration"""
-        self.generate_config(open(self.main_config_file(), 'w'))
+        with open(self.main_config_file(), 'w') as fobj:
+            self.generate_config(fobj)
 
     def check_writeable_uid_directory(self, path):
         """check given directory path exists, belongs to the user running the
@@ -1101,7 +1111,7 @@
             version = self.cube_version(pkg)
             infos.append('%s-%s' % (pkg, version))
         infos.append('cubicweb-%s' % str(self.cubicweb_version()))
-        return md5(';'.join(infos)).hexdigest()
+        return md5((';'.join(infos)).encode('ascii')).hexdigest()
 
     def load_configuration(self, **kw):
         """load instance's configuration files"""
@@ -1156,7 +1166,7 @@
 
     def _gettext_init(self):
         """set language for gettext"""
-        from cubicweb.gettext import translation
+        from cubicweb.cwgettext import translation
         path = join(self.apphome, 'i18n')
         for language in self.available_languages():
             self.info("loading language %s", language)
@@ -1181,13 +1191,8 @@
 
     def set_sources_mode(self, sources):
         if not 'all' in sources:
-            print 'warning: ignoring specified sources, requires a repository '\
-                  'configuration'
-
-    def migration_handler(self):
-        """return a migration handler instance"""
-        from cubicweb.migration import MigrationHelper
-        return MigrationHelper(self, verbosity=self.verbosity)
+            print('warning: ignoring specified sources, requires a repository '
+                  'configuration')
 
     def i18ncompile(self, langs=None):
         from cubicweb import i18n
--- a/cwctl.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/cwctl.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,6 +18,7 @@
 """the cubicweb-ctl tool, based on logilab.common.clcommands to
 provide a pluggable commands system.
 """
+from __future__ import print_function
 
 __docformat__ = "restructuredtext en"
 
@@ -28,7 +29,6 @@
 from warnings import warn, filterwarnings
 from os import remove, listdir, system, pathsep
 from os.path import exists, join, isfile, isdir, dirname, abspath
-from urlparse import urlparse
 
 try:
     from os import kill, getpgid
@@ -38,6 +38,8 @@
     def getpgid():
         """win32 getpgid implementation"""
 
+from six.moves.urllib.parse import urlparse
+
 from logilab.common.clcommands import CommandLine
 from logilab.common.shellutils import ASK
 from logilab.common.configuration import merge_options
@@ -113,15 +115,15 @@
         _allinstances = list_instances(regdir)
         if isfile(join(regdir, 'startorder')):
             allinstances = []
-            for line in file(join(regdir, 'startorder')):
+            for line in open(join(regdir, 'startorder')):
                 line = line.strip()
                 if line and not line.startswith('#'):
                     try:
                         _allinstances.remove(line)
                         allinstances.append(line)
                     except ValueError:
-                        print ('ERROR: startorder file contains unexistant '
-                               'instance %s' % line)
+                        print('ERROR: startorder file contains unexistant '
+                              'instance %s' % line)
             allinstances += _allinstances
         else:
             allinstances = _allinstances
@@ -146,7 +148,7 @@
         status = 0
         for appid in args:
             if askconfirm:
-                print '*'*72
+                print('*'*72)
                 if not ASK.confirm('%s instance %r ?' % (self.name, appid)):
                     continue
             try:
@@ -184,13 +186,13 @@
             forkcmd = None
         for appid in args:
             if askconfirm:
-                print '*'*72
+                print('*'*72)
                 if not ASK.confirm('%s instance %r ?' % (self.name, appid)):
                     continue
             if forkcmd:
                 status = system('%s %s' % (forkcmd, appid))
                 if status:
-                    print '%s exited with status %s' % (forkcmd, status)
+                    print('%s exited with status %s' % (forkcmd, status))
             else:
                 self.run_arg(appid)
 
@@ -224,19 +226,19 @@
         from cubicweb.migration import ConfigurationProblem
 
         if mode == 'all':
-            print 'CubicWeb %s (%s mode)' % (cwcfg.cubicweb_version(), cwcfg.mode)
-            print
+            print('CubicWeb %s (%s mode)' % (cwcfg.cubicweb_version(), cwcfg.mode))
+            print()
 
         if mode in ('all', 'config', 'configurations'):
-            print 'Available configurations:'
+            print('Available configurations:')
             for config in CONFIGURATIONS:
-                print '*', config.name
+                print('*', config.name)
                 for line in config.__doc__.splitlines():
                     line = line.strip()
                     if not line:
                         continue
-                    print '   ', line
-            print
+                    print('   ', line)
+            print()
 
         if mode in ('all', 'cubes'):
             cfgpb = ConfigurationProblem(cwcfg)
@@ -244,11 +246,11 @@
                 cubesdir = pathsep.join(cwcfg.cubes_search_path())
                 namesize = max(len(x) for x in cwcfg.available_cubes())
             except ConfigurationError as ex:
-                print 'No cubes available:', ex
+                print('No cubes available:', ex)
             except ValueError:
-                print 'No cubes available in %s' % cubesdir
+                print('No cubes available in %s' % cubesdir)
             else:
-                print 'Available cubes (%s):' % cubesdir
+                print('Available cubes (%s):' % cubesdir)
                 for cube in cwcfg.available_cubes():
                     try:
                         tinfo = cwcfg.cube_pkginfo(cube)
@@ -257,59 +259,59 @@
                     except (ConfigurationError, AttributeError) as ex:
                         tinfo = None
                         tversion = '[missing cube information: %s]' % ex
-                    print '* %s %s' % (cube.ljust(namesize), tversion)
+                    print('* %s %s' % (cube.ljust(namesize), tversion))
                     if self.config.verbose:
                         if tinfo:
                             descr = getattr(tinfo, 'description', '')
                             if not descr:
                                 descr = tinfo.__doc__
                             if descr:
-                                print '    '+ '    \n'.join(descr.splitlines())
+                                print('    '+ '    \n'.join(descr.splitlines()))
                         modes = detect_available_modes(cwcfg.cube_dir(cube))
-                        print '    available modes: %s' % ', '.join(modes)
-            print
+                        print('    available modes: %s' % ', '.join(modes))
+            print()
 
         if mode in ('all', 'instances'):
             try:
                 regdir = cwcfg.instances_dir()
             except ConfigurationError as ex:
-                print 'No instance available:', ex
-                print
+                print('No instance available:', ex)
+                print()
                 return
             instances = list_instances(regdir)
             if instances:
-                print 'Available instances (%s):' % regdir
+                print('Available instances (%s):' % regdir)
                 for appid in instances:
                     modes = cwcfg.possible_configurations(appid)
                     if not modes:
-                        print '* %s (BROKEN instance, no configuration found)' % appid
+                        print('* %s (BROKEN instance, no configuration found)' % appid)
                         continue
-                    print '* %s (%s)' % (appid, ', '.join(modes))
+                    print('* %s (%s)' % (appid, ', '.join(modes)))
                     try:
                         config = cwcfg.config_for(appid, modes[0])
                     except Exception as exc:
-                        print '    (BROKEN instance, %s)' % exc
+                        print('    (BROKEN instance, %s)' % exc)
                         continue
             else:
-                print 'No instance available in %s' % regdir
-            print
+                print('No instance available in %s' % regdir)
+            print()
 
         if mode == 'all':
             # configuration management problem solving
             cfgpb.solve()
             if cfgpb.warnings:
-                print 'Warnings:\n', '\n'.join('* '+txt for txt in cfgpb.warnings)
+                print('Warnings:\n', '\n'.join('* '+txt for txt in cfgpb.warnings))
             if cfgpb.errors:
-                print 'Errors:'
+                print('Errors:')
                 for op, cube, version, src in cfgpb.errors:
                     if op == 'add':
-                        print '* cube', cube,
+                        print('* cube', cube, end=' ')
                         if version:
-                            print ' version', version,
-                        print 'is not installed, but required by %s' % src
+                            print(' version', version, end=' ')
+                        print('is not installed, but required by %s' % src)
                     else:
-                        print '* cube %s version %s is installed, but version %s is required by %s' % (
-                            cube, cfgpb.cubes[cube], version, src)
+                        print('* cube %s version %s is installed, but version %s is required by %s' % (
+                            cube, cfgpb.cubes[cube], version, src))
 
 def check_options_consistency(config):
     if config.automatic and config.config_level > 0:
@@ -380,20 +382,20 @@
             templdirs = [cwcfg.cube_dir(cube)
                          for cube in cubes]
         except ConfigurationError as ex:
-            print ex
-            print '\navailable cubes:',
-            print ', '.join(cwcfg.available_cubes())
+            print(ex)
+            print('\navailable cubes:', end=' ')
+            print(', '.join(cwcfg.available_cubes()))
             return
         # create the registry directory for this instance
-        print '\n'+underline_title('Creating the instance %s' % appid)
+        print('\n'+underline_title('Creating the instance %s' % appid))
         create_dir(config.apphome)
         # cubicweb-ctl configuration
         if not self.config.automatic:
-            print '\n'+underline_title('Configuring the instance (%s.conf)'
-                                       % configname)
+            print('\n'+underline_title('Configuring the instance (%s.conf)'
+                                       % configname))
             config.input_config('main', self.config.config_level)
         # configuration'specific stuff
-        print
+        print()
         helper.bootstrap(cubes, self.config.automatic, self.config.config_level)
         # input for cubes specific options
         if not self.config.automatic:
@@ -402,23 +404,23 @@
                            and odict.get('level') <= self.config.config_level)
             for section in sections:
                 if section not in ('main', 'email', 'web'):
-                    print '\n' + underline_title('%s options' % section)
+                    print('\n' + underline_title('%s options' % section))
                     config.input_config(section, self.config.config_level)
         # write down configuration
         config.save()
         self._handle_win32(config, appid)
-        print '-> generated config %s' % config.main_config_file()
+        print('-> generated config %s' % config.main_config_file())
         # handle i18n files structure
         # in the first cube given
         from cubicweb import i18n
         langs = [lang for lang, _ in i18n.available_catalogs(join(templdirs[0], 'i18n'))]
         errors = config.i18ncompile(langs)
         if errors:
-            print '\n'.join(errors)
+            print('\n'.join(errors))
             if self.config.automatic \
                    or not ASK.confirm('error while compiling message catalogs, '
                                       'continue anyway ?'):
-                print 'creation not completed'
+                print('creation not completed')
                 return
         # create the additional data directory for this instance
         if config.appdatahome != config.apphome: # true in dev mode
@@ -427,9 +429,9 @@
         if config['uid']:
             from logilab.common.shellutils import chown
             # this directory should be owned by the uid of the server process
-            print 'set %s as owner of the data directory' % config['uid']
+            print('set %s as owner of the data directory' % config['uid'])
             chown(config.appdatahome, config['uid'])
-        print '\n-> creation done for %s\n' % repr(config.apphome)[1:-1]
+        print('\n-> creation done for %s\n' % repr(config.apphome)[1:-1])
         if not self.config.no_db_create:
             helper.postcreate(self.config.automatic, self.config.config_level)
 
@@ -487,7 +489,7 @@
             if ex.errno != errno.ENOENT:
                 raise
         confignames = ', '.join([config.name for config in configs])
-        print '-> instance %s (%s) deleted.' % (appid, confignames)
+        print('-> instance %s (%s) deleted.' % (appid, confignames))
 
 
 # instance commands ########################################################
@@ -551,7 +553,7 @@
 the --force option."
             raise ExecutionError(msg % (appid, pidf))
         if helper.start_server(config) == 1:
-            print 'instance %s started' % appid
+            print('instance %s started' % appid)
 
 
 def init_cmdline_log_threshold(config, loglevel):
@@ -606,7 +608,7 @@
         except OSError:
             # already removed by twistd
             pass
-        print 'instance %s stopped' % appid
+        print('instance %s stopped' % appid)
 
 
 class RestartInstanceCommand(StartInstanceCommand):
@@ -630,7 +632,7 @@
         # get instances in startorder
         for appid in args:
             if askconfirm:
-                print '*'*72
+                print('*'*72)
                 if not ASK.confirm('%s instance %r ?' % (self.name, appid)):
                     continue
             StopInstanceCommand(self.logger).stop_instance(appid)
@@ -677,14 +679,14 @@
         status = 0
         for mode in cwcfg.possible_configurations(appid):
             config = cwcfg.config_for(appid, mode)
-            print '[%s-%s]' % (appid, mode),
+            print('[%s-%s]' % (appid, mode), end=' ')
             try:
                 pidf = config['pid-file']
             except KeyError:
-                print 'buggy instance, pid file not specified'
+                print('buggy instance, pid file not specified')
                 continue
             if not exists(pidf):
-                print "doesn't seem to be running"
+                print("doesn't seem to be running")
                 status = 1
                 continue
             pid = int(open(pidf).read().strip())
@@ -692,10 +694,10 @@
             try:
                 getpgid(pid)
             except OSError:
-                print "should be running with pid %s but the process can not be found" % pid
+                print("should be running with pid %s but the process can not be found" % pid)
                 status = 1
                 continue
-            print "running with pid %s" % (pid)
+            print("running with pid %s" % (pid))
         return status
 
 class UpgradeInstanceCommand(InstanceCommandFork):
@@ -756,7 +758,7 @@
         )
 
     def upgrade_instance(self, appid):
-        print '\n' + underline_title('Upgrading the instance %s' % appid)
+        print('\n' + underline_title('Upgrading the instance %s' % appid))
         from logilab.common.changelog import Version
         config = cwcfg.config_for(appid)
         instance_running = exists(config['pid-file'])
@@ -767,11 +769,11 @@
             set_sources_mode(self.config.ext_sources or ('migration',))
         # get instance and installed versions for the server and the componants
         mih = config.migration_handler()
-        repo = mih.repo_connect()
+        repo = mih.repo
         vcconf = repo.get_versions()
         helper = self.config_helper(config, required=False)
         if self.config.force_cube_version:
-            for cube, version in self.config.force_cube_version.iteritems():
+            for cube, version in self.config.force_cube_version.items():
                 vcconf[cube] = Version(version)
         toupgrade = []
         for cube in config.cubes():
@@ -797,30 +799,30 @@
         # run cubicweb/componants migration scripts
         if self.config.fs_only or toupgrade:
             for cube, fromversion, toversion in toupgrade:
-                print '-> migration needed from %s to %s for %s' % (fromversion, toversion, cube)
+                print('-> migration needed from %s to %s for %s' % (fromversion, toversion, cube))
             with mih.cnx:
                 with mih.cnx.security_enabled(False, False):
                     mih.migrate(vcconf, reversed(toupgrade), self.config)
         else:
-            print '-> no data migration needed for instance %s.' % appid
+            print('-> no data migration needed for instance %s.' % appid)
         # rewrite main configuration file
         mih.rewrite_configuration()
         mih.shutdown()
         # handle i18n upgrade
         if not self.i18nupgrade(config):
             return
-        print
+        print()
         if helper:
             helper.postupgrade(repo)
-        print '-> instance migrated.'
+        print('-> instance migrated.')
         if instance_running and not (CWDEV or self.config.nostartstop):
             # restart instance through fork to get a proper environment, avoid
             # uicfg pb (and probably gettext catalogs, to check...)
             forkcmd = '%s start %s' % (sys.argv[0], appid)
             status = system(forkcmd)
             if status:
-                print '%s exited with status %s' % (forkcmd, status)
-        print
+                print('%s exited with status %s' % (forkcmd, status))
+        print()
 
     def i18nupgrade(self, config):
         # handle i18n upgrade:
@@ -832,10 +834,10 @@
         langs = [lang for lang, _ in i18n.available_catalogs(join(templdir, 'i18n'))]
         errors = config.i18ncompile(langs)
         if errors:
-            print '\n'.join(errors)
+            print('\n'.join(errors))
             if not ASK.confirm('Error while compiling message catalogs, '
                                'continue anyway?'):
-                print '-> migration not completed.'
+                print('-> migration not completed.')
                 return False
         return True
 
@@ -856,10 +858,9 @@
         config.quick_start = True
         if hasattr(config, 'set_sources_mode'):
             config.set_sources_mode(('migration',))
-        repo = config.migration_handler().repo_connect()
-        vcconf = repo.get_versions()
+        vcconf = config.repository().get_versions()
         for key in sorted(vcconf):
-            print key+': %s.%s.%s' % vcconf[key]
+            print(key+': %s.%s.%s' % vcconf[key])
 
 class ShellCommand(Command):
     """Run an interactive migration shell on an instance. This is a python shell
@@ -940,9 +941,9 @@
                 repo = get_repository(appuri)
                 cnx = connect(repo, login=login, password=pwd, mulcnx=False)
             except AuthenticationError as ex:
-                print ex
+                print(ex)
             except (KeyboardInterrupt, EOFError):
-                print
+                print()
                 sys.exit(0)
             else:
                 break
@@ -1003,7 +1004,7 @@
             config.init_cubes(repo.get_cubes())
         errors = config.i18ncompile()
         if errors:
-            print '\n'.join(errors)
+            print('\n'.join(errors))
 
 
 class ListInstancesCommand(Command):
@@ -1015,7 +1016,7 @@
         """run the command with its specific arguments"""
         regdir = cwcfg.instances_dir()
         for appid in sorted(listdir(regdir)):
-            print appid
+            print(appid)
 
 
 class ListCubesCommand(Command):
@@ -1026,7 +1027,7 @@
     def run(self, args):
         """run the command with its specific arguments"""
         for cube in cwcfg.available_cubes():
-            print cube
+            print(cube)
 
 class ConfigureInstanceCommand(InstanceCommand):
     """Configure instance.
@@ -1048,7 +1049,7 @@
     def configure_instance(self, appid):
         if self.config.param is not None:
             appcfg = cwcfg.config_for(appid)
-            for key, value in self.config.param.iteritems():
+            for key, value in self.config.param.items():
                 try:
                     appcfg.global_set_option(key, value)
                 except KeyError:
@@ -1138,17 +1139,15 @@
 def run(args):
     """command line tool"""
     import os
-    sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
-    sys.stderr = os.fdopen(sys.stderr.fileno(), 'w', 0)
     filterwarnings('default', category=DeprecationWarning)
     cwcfg.load_cwctl_plugins()
     try:
         CWCTL.run(args)
     except ConfigurationError as err:
-        print 'ERROR: ', err
+        print('ERROR: ', err)
         sys.exit(1)
     except ExecutionError as err:
-        print err
+        print(err)
         sys.exit(2)
 
 if __name__ == '__main__':
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cwgettext.py	Thu Dec 10 12:34:15 2015 +0100
@@ -0,0 +1,118 @@
+# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
+#
+# This file is part of CubicWeb.
+#
+# CubicWeb 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 2.1 of the License, or (at your option)
+# any later version.
+#
+# CubicWeb 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 CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
+
+import gettext
+
+
+class cwGNUTranslations(gettext.GNUTranslations):
+    # The encoding of a msgctxt and a msgid in a .mo file is
+    # msgctxt + "\x04" + msgid (gettext version >= 0.15)
+    CONTEXT_ENCODING = "%s\x04%s"
+
+    def pgettext(self, context, message):
+        ctxt_msg_id = self.CONTEXT_ENCODING % (context, message)
+        missing = object()
+        tmsg = self._catalog.get(ctxt_msg_id, missing)
+        if tmsg is missing:
+            if self._fallback:
+                return self._fallback.pgettext(context, message)
+            return message
+        # Encode the Unicode tmsg back to an 8-bit string, if possible
+        if self._output_charset:
+            return tmsg.encode(self._output_charset)
+        elif self._charset:
+            return tmsg.encode(self._charset)
+        return tmsg
+
+    def lpgettext(self, context, message):
+        ctxt_msg_id = self.CONTEXT_ENCODING % (context, message)
+        missing = object()
+        tmsg = self._catalog.get(ctxt_msg_id, missing)
+        if tmsg is missing:
+            if self._fallback:
+                return self._fallback.lpgettext(context, message)
+            return message
+        if self._output_charset:
+            return tmsg.encode(self._output_charset)
+        return tmsg.encode(locale.getpreferredencoding())
+
+    def npgettext(self, context, msgid1, msgid2, n):
+        ctxt_msg_id = self.CONTEXT_ENCODING % (context, msgid1)
+        try:
+            tmsg = self._catalog[(ctxt_msg_id, self.plural(n))]
+            if self._output_charset:
+                return tmsg.encode(self._output_charset)
+            elif self._charset:
+                return tmsg.encode(self._charset)
+            return tmsg
+        except KeyError:
+            if self._fallback:
+                return self._fallback.npgettext(context, msgid1, msgid2, n)
+            if n == 1:
+                return msgid1
+            else:
+                return msgid2        
+
+    def lnpgettext(self, context, msgid1, msgid2, n):
+        ctxt_msg_id = self.CONTEXT_ENCODING % (context, msgid1)
+        try:
+            tmsg = self._catalog[(ctxt_msg_id, self.plural(n))]
+            if self._output_charset:
+                return tmsg.encode(self._output_charset)
+            return tmsg.encode(locale.getpreferredencoding())
+        except KeyError:
+            if self._fallback:
+                return self._fallback.lnpgettext(context, msgid1, msgid2, n)
+            if n == 1:
+                return msgid1
+            else:
+                return msgid2
+
+    def upgettext(self, context, message):
+        ctxt_message_id = self.CONTEXT_ENCODING % (context, message)
+        missing = object()
+        tmsg = self._catalog.get(ctxt_message_id, missing)
+        if tmsg is missing:
+            # XXX logilab patch for compat w/ catalog generated by cw < 3.5
+            return self.ugettext(message)
+            if self._fallback:
+                return self._fallback.upgettext(context, message)
+            return unicode(message)
+        return tmsg
+
+    def unpgettext(self, context, msgid1, msgid2, n):
+        ctxt_message_id = self.CONTEXT_ENCODING % (context, msgid1)
+        try:
+            tmsg = self._catalog[(ctxt_message_id, self.plural(n))]
+        except KeyError:
+            if self._fallback:
+                return self._fallback.unpgettext(context, msgid1, msgid2, n)
+            if n == 1:
+                tmsg = unicode(msgid1)
+            else:
+                tmsg = unicode(msgid2)
+        return tmsg
+
+
+def translation(domain, localedir=None, languages=None,
+                class_=None, fallback=False, codeset=None):
+    if class_ is None:
+        class_ = cwGNUTranslations
+    return gettext.translation(domain, localedir=localedir,
+                               languages=languages, class_=class_,
+                               fallback=fallback, codeset=codeset)
--- a/cwvreg.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/cwvreg.py	Thu Dec 10 12:34:15 2015 +0100
@@ -20,7 +20,7 @@
 """
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 import sys
 from os.path import join, dirname, realpath
@@ -28,6 +28,8 @@
 from datetime import datetime, date, time, timedelta
 from functools import reduce
 
+from six import text_type, binary_type
+
 from logilab.common.decorators import cached, clear_cache
 from logilab.common.deprecation import deprecated, class_deprecated
 from logilab.common.modutils import cleanup_sys_modules
@@ -221,9 +223,9 @@
         """
         obj = self.select(oid, req, rset=rset, **kwargs)
         res = obj.render(**kwargs)
-        if isinstance(res, unicode):
+        if isinstance(res, text_type):
             return res.encode(req.encoding)
-        assert isinstance(res, str)
+        assert isinstance(res, binary_type)
         return res
 
     def possible_views(self, req, rset=None, **kwargs):
@@ -382,7 +384,7 @@
         return [item for item in super(CWRegistryStore, self).items()
                 if not item[0] in ('propertydefs', 'propertyvalues')]
     def iteritems(self):
-        return (item for item in super(CWRegistryStore, self).iteritems()
+        return (item for item in super(CWRegistryStore, self).items()
                 if not item[0] in ('propertydefs', 'propertyvalues'))
 
     def values(self):
@@ -492,7 +494,7 @@
         """
         self.schema = schema
         for registry, regcontent in self.items():
-            for objects in regcontent.itervalues():
+            for objects in regcontent.values():
                 for obj in objects:
                     obj.schema = schema
 
@@ -543,7 +545,7 @@
                     self.unregister(obj)
         super(CWRegistryStore, self).initialization_completed()
         if 'uicfg' in self: # 'uicfg' is not loaded in a pure repository mode
-            for rtags in self['uicfg'].itervalues():
+            for rtags in self['uicfg'].values():
                 for rtag in rtags:
                     # don't check rtags if we don't want to cleanup_unused_appobjects
                     rtag.init(self.schema, check=self.config.cleanup_unused_appobjects)
@@ -576,7 +578,7 @@
         if withsitewide:
             return sorted(k for k in self['propertydefs']
                           if not k.startswith('sources.'))
-        return sorted(k for k, kd in self['propertydefs'].iteritems()
+        return sorted(k for k, kd in self['propertydefs'].items()
                       if not kd['sitewide'] and not k.startswith('sources.'))
 
     def register_property(self, key, type, help, default=None, vocabulary=None,
@@ -653,4 +655,3 @@
     'TZTime':     time,
     'Interval':   timedelta,
     })
-
--- a/dataimport/csv.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/dataimport/csv.py	Thu Dec 10 12:34:15 2015 +0100
@@ -16,18 +16,20 @@
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """Functions to help importing CSV data"""
+from __future__ import absolute_import, print_function
 
-from __future__ import absolute_import
-
+import codecs
 import csv as csvmod
 import warnings
 import os.path as osp
 
+from six import PY2, PY3, string_types
+
 from logilab.common import shellutils
 
 
 def count_lines(stream_or_filename):
-    if isinstance(stream_or_filename, basestring):
+    if isinstance(stream_or_filename, string_types):
         f = open(stream_or_filename)
     else:
         f = stream_or_filename
@@ -48,10 +50,8 @@
     if quote is not None:
         quotechar = quote
         warnings.warn("[3.20] 'quote' kwarg is deprecated, use 'quotechar' instead")
-    if isinstance(stream_or_path, basestring):
-        if not osp.exists(stream_or_path):
-            raise Exception("file doesn't exists: %s" % stream_or_path)
-        stream = open(stream_or_path)
+    if isinstance(stream_or_path, string_types):
+        stream = open(stream_or_path, 'rb')
     else:
         stream = stream_or_path
     rowcount = count_lines(stream)
@@ -64,7 +64,7 @@
         yield urow
         if withpb:
             pb.update()
-    print ' %s rows imported' % rowcount
+    print(' %s rows imported' % rowcount)
 
 
 def ucsvreader(stream, encoding='utf-8', delimiter=',', quotechar='"',
@@ -77,6 +77,8 @@
     separators) will be skipped. This is useful for Excel exports which may be
     full of such lines.
     """
+    if PY3:
+        stream = codecs.getreader(encoding)(stream)
     if separator is not None:
         delimiter = separator
         warnings.warn("[3.20] 'separator' kwarg is deprecated, use 'delimiter' instead")
@@ -86,28 +88,33 @@
     it = iter(csvmod.reader(stream, delimiter=delimiter, quotechar=quotechar))
     if not ignore_errors:
         if skipfirst:
-            it.next()
+            next(it)
         for row in it:
-            decoded = [item.decode(encoding) for item in row]
+            if PY2:
+                decoded = [item.decode(encoding) for item in row]
+            else:
+                decoded = row
             if not skip_empty or any(decoded):
                 yield decoded
     else:
         if skipfirst:
             try:
-                row = it.next()
+                row = next(it)
             except csvmod.Error:
                 pass
         # Safe version, that can cope with error in CSV file
         while True:
             try:
-                row = it.next()
+                row = next(it)
             # End of CSV, break
             except StopIteration:
                 break
             # Error in CSV, ignore line and continue
             except csvmod.Error:
                 continue
-            decoded = [item.decode(encoding) for item in row]
+            if PY2:
+                decoded = [item.decode(encoding) for item in row]
+            else:
+                decoded = row
             if not skip_empty or any(decoded):
                 yield decoded
-
--- a/dataimport/deprecated.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/dataimport/deprecated.py	Thu Dec 10 12:34:15 2015 +0100
@@ -58,10 +58,13 @@
 .. BUG file with one column are not parsable
 .. TODO rollback() invocation is not possible yet
 """
+from __future__ import print_function
 
 import sys
 import traceback
-from StringIO import StringIO
+from io import StringIO
+
+from six import add_metaclass
 
 from logilab.common import attrdict, shellutils
 from logilab.common.date import strptime
@@ -78,7 +81,7 @@
 
     >>> data = lazytable(ucsvreader(open(filename)))
     """
-    header = reader.next()
+    header = next(reader)
     for row in reader:
         yield dict(zip(header, row))
 
@@ -103,7 +106,7 @@
 
 @deprecated('[3.21] deprecated')
 def tell(msg):
-    print msg
+    print(msg)
 
 
 @deprecated('[3.21] deprecated')
@@ -115,9 +118,9 @@
     return answer == 'Y'
 
 
+@add_metaclass(class_deprecated)
 class catch_error(object):
     """Helper for @contextmanager decorator."""
-    __metaclass__ = class_deprecated
     __deprecation_warning__ = '[3.21] deprecated'
 
     def __init__(self, ctl, key='unexpected error', msg=None):
@@ -166,7 +169,9 @@
                 if res[dest] is None:
                     break
         except ValueError as err:
-            raise ValueError('error with %r field: %s' % (src, err)), None, sys.exc_info()[-1]
+            exc = ValueError('error with %r field: %s' % (src, err))
+            exc.__traceback__ = sys.exc_info()[-1]
+            raise exc
     return res
 
 
@@ -254,6 +259,7 @@
             if k is not None and len(v) > 1]
 
 
+@add_metaclass(class_deprecated)
 class ObjectStore(object):
     """Store objects in memory for *faster* validation (development mode)
 
@@ -264,7 +270,6 @@
     >>> group = store.prepare_insert_entity('CWUser', name=u'unknown')
     >>> store.prepare_insert_relation(user, 'in_group', group)
     """
-    __metaclass__ = class_deprecated
     __deprecation_warning__ = '[3.21] use the new importer API'
 
     def __init__(self):
@@ -289,7 +294,7 @@
         """Given an entity type and eid, updates the corresponding fake entity with specified
         attributes and inlined relations.
         """
-        assert eid in self.types[etype], 'Trying to update with wrong type {}'.format(etype)
+        assert eid in self.types[etype], 'Trying to update with wrong type %s' % etype
         data = self.eids[eid]
         data.update(kwargs)
 
@@ -335,6 +340,7 @@
         self.prepare_insert_relation(eid_from, rtype, eid_to, **kwargs)
 
 
+@add_metaclass(class_deprecated)
 class CWImportController(object):
     """Controller of the data import process.
 
@@ -343,7 +349,6 @@
     >>> ctl.data = dict_of_data_tables
     >>> ctl.run()
     """
-    __metaclass__ = class_deprecated
     __deprecation_warning__ = '[3.21] use the new importer API'
 
     def __init__(self, store, askerror=0, catcherrors=None, tell=tell,
@@ -421,7 +426,7 @@
                     self.tell(pformat(sorted(error[1])))
 
     def _print_stats(self):
-        nberrors = sum(len(err) for err in self.errors.itervalues())
+        nberrors = sum(len(err) for err in self.errors.values())
         self.tell('\nImport statistics: %i entities, %i types, %i relations and %i errors'
                   % (self.store.nb_inserted_entities,
                      self.store.nb_inserted_types,
@@ -456,5 +461,3 @@
             return callfunc_every(self.store.commit,
                                   self.commitevery,
                                   self.get_data(datakey))
-
-
--- a/dataimport/importer.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/dataimport/importer.py	Thu Dec 10 12:34:15 2015 +0100
@@ -69,7 +69,7 @@
     def use_extid_as_cwuri_filter(extentities):
         for extentity in extentities:
             if extentity.extid not in extid2eid:
-                extentity.values.setdefault('cwuri', set([unicode(extentity.extid)]))
+                extentity.values.setdefault('cwuri', set([extentity.extid.decode('utf-8')]))
             yield extentity
     return use_extid_as_cwuri_filter
 
@@ -83,15 +83,15 @@
 
     def __init__(self, cnx, source=None):
         self.cnx = cnx
-        self._rql_template = 'Any S,O WHERE S {} O'
+        self._rql_template = 'Any S,O WHERE S %s O'
         self._kwargs = {}
         if source is not None:
-            self._rql_template += ', S cw_source SO, O cw_source SO, SO eid %(s)s'
+            self._rql_template += ', S cw_source SO, O cw_source SO, SO eid %%(s)s'
             self._kwargs['s'] = source.eid
 
     def __getitem__(self, rtype):
         """Return a set of (subject, object) eids already related by `rtype`"""
-        rql = self._rql_template.format(rtype)
+        rql = self._rql_template % rtype
         return set(tuple(x) for x in self.cnx.execute(rql, self._kwargs))
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dataimport/massive_store.py	Thu Dec 10 12:34:15 2015 +0100
@@ -0,0 +1,742 @@
+# coding: utf-8
+# copyright 2015 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
+#
+# This file is part of CubicWeb.
+#
+# CubicWeb 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 2.1 of the License, or (at your option)
+# any later version.
+#
+# CubicWeb 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 CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
+
+import logging
+from datetime import datetime
+from collections import defaultdict
+from io import StringIO
+
+from six.moves import range
+
+from yams.constraints import SizeConstraint
+
+from psycopg2 import ProgrammingError
+
+from cubicweb.dataimport import stores, pgstore
+from cubicweb.utils import make_uid
+from cubicweb.server.sqlutils import SQL_PREFIX
+
+
+class MassiveObjectStore(stores.RQLObjectStore):
+    """
+    Store for massive import of data, with delayed insertion of meta data.
+
+    WARNINGS:
+   - This store may be only used with PostgreSQL for now, as it relies
+     on the COPY FROM method, and on specific PostgreSQL tables to get all
+     the indexes.
+   - This store can only insert relations that are not inlined (i.e.,
+     which do *not* have inlined=True in their definition in the schema).
+
+   It should be used as follows:
+
+       store = MassiveObjectStore(cnx)
+       store.init_rtype_table('Person', 'lives_in', 'Location')
+       ...
+
+       store.prepare_insert_entity('Person', subj_iid_attribute=person_iid, ...)
+       store.prepare_insert_entity('Location', obj_iid_attribute=location_iid, ...)
+       ...
+
+       # subj_iid_attribute and obj_iid_attribute are argument names
+       # chosen by the user (e.g. "cwuri"). These names can be identical.
+       # person_iid and location_iid are unique IDs and depend on the data
+       # (e.g URI).
+       store.flush()
+       store.relate_by_iid(person_iid, 'lives_in', location_iid)
+       # For example:
+       store.prepare_insert_entity('Person',
+                                   cwuri='http://dbpedia.org/toto',
+                                   name='Toto')
+       store.prepare_insert_entity('Location',
+                                   uri='http://geonames.org/11111',
+                                   name='Somewhere')
+       store.flush()
+       store.relate_by_iid('http://dbpedia.org/toto',
+                           'lives_in',
+                           'http://geonames.org/11111')
+       # Finally
+       store.convert_relations('Person', 'lives_in', 'Location',
+                               'subj_iid_attribute', 'obj_iid_attribute')
+       # For the previous example:
+       store.convert_relations('Person', 'lives_in', 'Location', 'cwuri', 'uri')
+       ...
+       store.commit()
+       store.finish()
+    """
+    # size of eid range reserved by the store for each batch
+    eids_seq_range = 10000
+    # initial eid (None means use the value in the db)
+    eids_seq_start = None
+    # max size of the iid, used to create the iid_eid conversion table
+    iid_maxsize = 1024
+
+    def __init__(self, cnx,
+                 on_commit_callback=None, on_rollback_callback=None,
+                 slave_mode=False,
+                 source=None):
+        """ Create a MassiveObject store, with the following attributes:
+
+        - cnx: CubicWeb cnx
+        """
+        super(MassiveObjectStore, self).__init__(cnx)
+        self.logger = logging.getLogger('dataimport.massive_store')
+        self._cnx = cnx
+        self.sql = cnx.system_sql
+        self._data_uri_relations = defaultdict(list)
+
+        # etypes for which we have a uri_eid_%(etype)s table
+        self._init_uri_eid = set()
+        # etypes for which we have a uri_eid_%(e)s_idx index
+        self._uri_eid_inserted = set()
+        # set of rtypes for which we have a %(rtype)s_relation_iid_tmp table
+        self._uri_rtypes = set()
+        # set of etypes whose tables are created
+        self._entities = set()
+        # set of rtypes for which we have a %(rtype)s_relation_tmp table
+        self._rtypes = set()
+
+        self.slave_mode = slave_mode
+        self.default_values = get_default_values(cnx.vreg.schema)
+        pg_schema = cnx.repo.config.system_source_config.get('db-namespace') or 'public'
+        self._dbh = PGHelper(self._cnx, pg_schema)
+        self._data_entities = defaultdict(list)
+        self._data_relations = defaultdict(list)
+        self._now = datetime.now()
+        self._default_cwuri = make_uid('_auto_generated')
+        self._count_cwuri = 0
+        self.on_commit_callback = on_commit_callback
+        self.on_rollback_callback = on_rollback_callback
+        # Do our meta tables already exist?
+        self._init_massive_metatables()
+        # Internal markers of initialization
+        if self.eids_seq_start is not None and not self.slave_mode:
+            self._cnx.system_sql(self._cnx.repo.system_source.dbhelper.sql_restart_numrange(
+                'entities_id_seq', initial_value=self.eids_seq_start + 1))
+            cnx.commit()
+        self.get_next_eid = lambda g=self._get_eid_gen(): next(g)
+        # recreate then when self.finish() is called
+        if not self.slave_mode:
+            self._drop_metatables_constraints()
+        if source is None:
+            source = cnx.repo.system_source
+        self.source = source
+        self._etype_eid_idx = dict(cnx.execute('Any XN,X WHERE X is CWEType, X name XN'))
+        cnx.read_security = False
+        cnx.write_security = False
+
+    ### INIT FUNCTIONS ########################################################
+
+    def init_rtype_table(self, etype_from, rtype, etype_to):
+        """ Build temporary table for standard rtype """
+        # Create an uri_eid table for each etype for a better
+        # control of which etype is concerned by a particular
+        # possibly multivalued relation.
+        for etype in (etype_from, etype_to):
+            if etype and etype not in self._init_uri_eid:
+                self._init_uri_eid_table(etype)
+        if rtype not in self._uri_rtypes:
+            # Create the temporary table
+            if not self._cnx.repo.schema.rschema(rtype).inlined:
+                try:
+                    sql = 'CREATE TABLE %(r)s_relation_iid_tmp (uri_from character ' \
+                          'varying(%(s)s), uri_to character varying(%(s)s))'
+                    self.sql(sql % {'r': rtype, 's': self.iid_maxsize})
+                except ProgrammingError:
+                    # XXX Already exist (probably due to multiple import)
+                    pass
+            else:
+                self.logger.warning("inlined relation %s: cannot insert it", rtype)
+            # Add it to the initialized set
+            self._uri_rtypes.add(rtype)
+
+    def _init_uri_eid_table(self, etype):
+        """ Build a temporary table for id/eid convertion
+        """
+        try:
+            sql = "CREATE TABLE uri_eid_%(e)s (uri character varying(%(size)s), eid integer)"
+            self.sql(sql % {'e': etype.lower(), 'size': self.iid_maxsize,})
+        except ProgrammingError:
+            # XXX Already exist (probably due to multiple import)
+            pass
+        # Add it to the initialized set
+        self._init_uri_eid.add(etype)
+
+    def _init_massive_metatables(self):
+        # Check if our tables are not already created (i.e. a restart)
+        self._initialized_table_created = self._dbh.table_exists('cwmassive_initialized')
+        self._constraint_table_created = self._dbh.table_exists('cwmassive_constraints')
+        self._metadata_table_created = self._dbh.table_exists('cwmassive_metadata')
+
+    ### RELATE FUNCTION #######################################################
+
+    def relate_by_iid(self, iid_from, rtype, iid_to):
+        """Add new relation based on the internal id (iid)
+        of the entities (not the eid)"""
+        # Push data
+        if isinstance(iid_from, unicode):
+            iid_from = iid_from.encode('utf-8')
+        if isinstance(iid_to, unicode):
+            iid_to = iid_to.encode('utf-8')
+        self._data_uri_relations[rtype].append({'uri_from': iid_from, 'uri_to': iid_to})
+
+    ### FLUSH FUNCTIONS #######################################################
+
+    def flush_relations(self):
+        """ Flush the relations data
+        """
+        for rtype, data in self._data_uri_relations.items():
+            if not data:
+                self.logger.info('No data for rtype %s', rtype)
+            buf = StringIO('\n'.join(['%(uri_from)s\t%(uri_to)s' % d for d in data]))
+            if not buf:
+                self.logger.info('Empty Buffer for rtype %s', rtype)
+                continue
+            cursor = self._cnx.cnxset.cu
+            if not self._cnx.repo.schema.rschema(rtype).inlined:
+                cursor.copy_from(buf, '%s_relation_iid_tmp' % rtype.lower(),
+                                 null='NULL', columns=('uri_from', 'uri_to'))
+            else:
+                self.logger.warning("inlined relation %s: cannot insert it", rtype)
+            buf.close()
+            # Clear data cache
+            self._data_uri_relations[rtype] = []
+
+    def fill_uri_eid_table(self, etype, uri_label):
+        """ Fill the uri_eid table
+        """
+        self.logger.info('Fill uri_eid for etype %s', etype)
+        sql = 'INSERT INTO uri_eid_%(e)s SELECT cw_%(l)s, cw_eid FROM cw_%(e)s'
+        self.sql(sql % {'l': uri_label, 'e': etype.lower()})
+        # Add indexes
+        self.sql('CREATE INDEX uri_eid_%(e)s_idx ON uri_eid_%(e)s' '(uri)' % {'e': etype.lower()})
+        # Set the etype as converted
+        self._uri_eid_inserted.add(etype)
+
+    def convert_relations(self, etype_from, rtype, etype_to,
+                          uri_label_from='cwuri', uri_label_to='cwuri'):
+        """ Flush the converted relations
+        """
+        # Always flush relations to be sure
+        self.logger.info('Convert relations %s %s %s', etype_from, rtype, etype_to)
+        self.flush_relations()
+        if uri_label_from and etype_from not in self._uri_eid_inserted:
+            self.fill_uri_eid_table(etype_from, uri_label_from)
+        if uri_label_to and etype_to not in self._uri_eid_inserted:
+            self.fill_uri_eid_table(etype_to, uri_label_to)
+        if self._cnx.repo.schema.rschema(rtype).inlined:
+            self.logger.warning("Can't insert inlined relation %s", rtype)
+            return
+        if uri_label_from and uri_label_to:
+            sql = '''INSERT INTO %(r)s_relation (eid_from, eid_to) SELECT DISTINCT O1.eid, O2.eid
+            FROM %(r)s_relation_iid_tmp AS T, uri_eid_%(ef)s as O1, uri_eid_%(et)s as O2
+            WHERE O1.uri=T.uri_from AND O2.uri=T.uri_to AND NOT EXISTS (
+            SELECT 1 FROM %(r)s_relation AS TT WHERE TT.eid_from=O1.eid AND TT.eid_to=O2.eid);
+            '''
+        elif uri_label_to:
+            sql = '''INSERT INTO %(r)s_relation (eid_from, eid_to) SELECT DISTINCT
+            CAST(T.uri_from AS INTEGER), O1.eid
+            FROM %(r)s_relation_iid_tmp AS T, uri_eid_%(et)s as O1
+            WHERE O1.uri=T.uri_to AND NOT EXISTS (
+            SELECT 1 FROM %(r)s_relation AS TT WHERE
+            TT.eid_from=CAST(T.uri_from AS INTEGER) AND TT.eid_to=O1.eid);
+            '''
+        elif uri_label_from:
+            sql = '''INSERT INTO %(r)s_relation (eid_from, eid_to) SELECT DISTINCT O1.eid, T.uri_to
+            O1.eid, CAST(T.uri_to AS INTEGER)
+            FROM %(r)s_relation_iid_tmp AS T, uri_eid_%(ef)s as O1
+            WHERE O1.uri=T.uri_from AND NOT EXISTS (
+            SELECT 1 FROM %(r)s_relation AS TT WHERE
+            TT.eid_from=O1.eid AND TT.eid_to=CAST(T.uri_to AS INTEGER));
+            '''
+        try:
+            self.sql(sql % {'r': rtype.lower(),
+                            'et': etype_to.lower() if etype_to else u'',
+                            'ef': etype_from.lower() if etype_from else u''})
+        except Exception as ex:
+            self.logger.error("Can't insert relation %s: %s", rtype, ex)
+
+    ### SQL UTILITIES #########################################################
+
+    def drop_and_store_indexes_constraints(self, tablename):
+        # Drop indexes and constraints
+        if not self._constraint_table_created:
+            # Create a table to save the constraints
+            # Allow reload even after crash
+            sql = "CREATE TABLE cwmassive_constraints (origtable text, query text, type varchar(256))"
+            self.sql(sql)
+            self._constraint_table_created = True
+        self._drop_table_constraints_indexes(tablename)
+
+    def _drop_table_constraints_indexes(self, tablename):
+        """ Drop and store table constraints and indexes """
+        indexes, constraints = self._dbh.application_indexes_constraints(tablename)
+        for name, query in constraints.items():
+            sql = 'INSERT INTO cwmassive_constraints VALUES (%(e)s, %(c)s, %(t)s)'
+            self.sql(sql, {'e': tablename, 'c': query, 't': 'constraint'})
+            sql = 'ALTER TABLE %s DROP CONSTRAINT %s CASCADE' % (tablename, name)
+            self.sql(sql)
+        for name, query in indexes.items():
+            sql = 'INSERT INTO cwmassive_constraints VALUES (%(e)s, %(c)s, %(t)s)'
+            self.sql(sql, {'e': tablename, 'c': query, 't': 'index'})
+            sql = 'DROP INDEX %s' % name
+            self.sql(sql)
+
+    def reapply_constraint_index(self, tablename):
+        if not self._dbh.table_exists('cwmassive_constraints'):
+            self.logger.info('The table cwmassive_constraints does not exist')
+            return
+        sql = 'SELECT query FROM cwmassive_constraints WHERE origtable = %(e)s'
+        crs = self.sql(sql, {'e': tablename})
+        for query, in crs.fetchall():
+            self.sql(query)
+            self.sql('DELETE FROM cwmassive_constraints WHERE origtable = %(e)s '
+                     'AND query = %(q)s', {'e': tablename, 'q': query})
+
+    def _drop_metatables_constraints(self):
+        """ Drop all the constraints for the meta data"""
+        for tablename in ('created_by_relation', 'owned_by_relation',
+                          'is_instance_of_relation', 'is_relation',
+                          'entities'):
+            self.drop_and_store_indexes_constraints(tablename)
+
+    def _create_metatables_constraints(self):
+        """ Create all the constraints for the meta data"""
+        for tablename in ('entities',
+                          'created_by_relation', 'owned_by_relation',
+                          'is_instance_of_relation', 'is_relation'):
+            # Indexes and constraints
+            self.reapply_constraint_index(tablename)
+
+    def init_relation_table(self, rtype):
+        """ Get and remove all indexes for performance sake """
+        # Create temporary table
+        if not self.slave_mode and rtype not in self._rtypes:
+            sql = "CREATE TABLE %s_relation_tmp (eid_from integer, eid_to integer)" % rtype.lower()
+            self.sql(sql)
+            # Drop indexes and constraints
+            tablename = '%s_relation' % rtype.lower()
+            self.drop_and_store_indexes_constraints(tablename)
+            # Push the etype in the initialized table for easier restart
+            self.init_create_initialized_table()
+            sql = 'INSERT INTO cwmassive_initialized VALUES (%(e)s, %(t)s)'
+            self.sql(sql, {'e': rtype, 't': 'rtype'})
+            # Mark rtype as "initialized" for faster check
+            self._rtypes.add(rtype)
+
+    def init_create_initialized_table(self):
+        """ Create the cwmassive initialized table
+        """
+        if not self._initialized_table_created:
+            sql = "CREATE TABLE cwmassive_initialized (retype text, type varchar(128))"
+            self.sql(sql)
+            self._initialized_table_created = True
+
+    def init_etype_table(self, etype):
+        """ Add eid sequence to a particular etype table and
+        remove all indexes for performance sake """
+        if etype not in self._entities:
+            # Only for non-initialized etype and not slave mode store
+            if not self.slave_mode:
+                if self.eids_seq_range is None:
+                    # Eids are directly set by the entities_id_seq.
+                    # We attach this sequence to all the created etypes.
+                    sql = ("ALTER TABLE cw_%s ALTER COLUMN cw_eid "
+                           "SET DEFAULT nextval('entities_id_seq')" % etype.lower())
+                    self.sql(sql)
+                # Drop indexes and constraints
+                tablename = 'cw_%s' % etype.lower()
+                self.drop_and_store_indexes_constraints(tablename)
+                # Push the etype in the initialized table for easier restart
+                self.init_create_initialized_table()
+                sql = 'INSERT INTO cwmassive_initialized VALUES (%(e)s, %(t)s)'
+                self.sql(sql, {'e': etype, 't': 'etype'})
+            # Mark etype as "initialized" for faster check
+            self._entities.add(etype)
+
+
+    ### ENTITIES CREATION #####################################################
+
+    def _get_eid_gen(self):
+        """ Function getting the next eid. This is done by preselecting
+        a given number of eids from the 'entities_id_seq', and then
+        storing them"""
+        while True:
+            last_eid = self._cnx.repo.system_source.create_eid(self._cnx, self.eids_seq_range)
+            for eid in range(last_eid - self.eids_seq_range + 1, last_eid + 1):
+                yield eid
+
+    def _apply_default_values(self, etype, kwargs):
+        """Apply the default values for a given etype, attribute and value."""
+        default_values = self.default_values[etype]
+        missing_keys = set(default_values) - set(kwargs)
+        kwargs.update((key, default_values[key]) for key in missing_keys)
+
+    # store api ################################################################
+
+    def prepare_insert_entity(self, etype, **kwargs):
+        """Given an entity type, attributes and inlined relations, returns the inserted entity's
+        eid.
+        """
+        # Init the table if necessary
+        self.init_etype_table(etype)
+        # Add meta data if not given
+        if 'modification_date' not in kwargs:
+            kwargs['modification_date'] = self._now
+        if 'creation_date' not in kwargs:
+            kwargs['creation_date'] = self._now
+        if 'cwuri' not in kwargs:
+            kwargs['cwuri'] = self._default_cwuri + str(self._count_cwuri)
+            self._count_cwuri += 1
+        if 'eid' not in kwargs and self.eids_seq_range is not None:
+            # If eid is not given and the eids sequence is set,
+            # use the value from the sequence
+            kwargs['eid'] = self.get_next_eid()
+        self._apply_default_values(etype, kwargs)
+        self._data_entities[etype].append(kwargs)
+        return kwargs.get('eid')
+
+    def prepare_insert_relation(self, eid_from, rtype, eid_to, **kwargs):
+        """Insert into the database a  relation ``rtype`` between entities with eids ``eid_from``
+        and ``eid_to``.
+        """
+        # Init the table if necessary
+        self.init_relation_table(rtype)
+        self._data_relations[rtype].append({'eid_from': eid_from, 'eid_to': eid_to})
+
+    def flush(self):
+        """Flush the data"""
+        self.flush_entities()
+        self.flush_internal_relations()
+        self.flush_relations()
+
+    def commit(self):
+        """Commit the database transaction."""
+        self.on_commit()
+        super(MassiveObjectStore, self).commit()
+
+    def finish(self):
+        """Remove temporary tables and columns."""
+        self.logger.info("Start cleaning")
+        if self.slave_mode:
+            raise RuntimeError('Store cleanup is not allowed in slave mode')
+        self.logger.info("Start cleaning")
+        # Cleanup relations tables
+        for etype in self._init_uri_eid:
+            self.sql('DROP TABLE uri_eid_%s' % etype.lower())
+        # Remove relations tables
+        for rtype in self._uri_rtypes:
+            if not self._cnx.repo.schema.rschema(rtype).inlined:
+                self.sql('DROP TABLE %(r)s_relation_iid_tmp' % {'r': rtype})
+            else:
+                self.logger.warning("inlined relation %s: no cleanup to be done for it" % rtype)
+        # Get all the initialized etypes/rtypes
+        if self._dbh.table_exists('cwmassive_initialized'):
+            crs = self.sql('SELECT retype, type FROM cwmassive_initialized')
+            for retype, _type in crs.fetchall():
+                self.logger.info('Cleanup for %s' % retype)
+                if _type == 'etype':
+                    # Cleanup entities tables - Recreate indexes
+                    self._cleanup_entities(retype)
+                elif _type == 'rtype':
+                    # Cleanup relations tables
+                    self._cleanup_relations(retype)
+                self.sql('DELETE FROM cwmassive_initialized WHERE retype = %(e)s',
+                         {'e': retype})
+        # Create meta constraints (entities, is_instance_of, ...)
+        self._create_metatables_constraints()
+        # Delete the meta data table
+        for table_name in ('cwmassive_initialized', 'cwmassive_constraints', 'cwmassive_metadata'):
+            if self._dbh.table_exists(table_name):
+                self.sql('DROP TABLE %s' % table_name)
+        self.commit()
+
+    ### FLUSH #################################################################
+
+    def on_commit(self):
+        if self.on_commit_callback:
+            self.on_commit_callback()
+
+    def on_rollback(self, exc, etype, data):
+        if self.on_rollback_callback:
+            self.on_rollback_callback(exc, etype, data)
+            self._cnx.rollback()
+        else:
+            raise exc
+
+    def flush_internal_relations(self):
+        """ Flush the relations data
+        """
+        for rtype, data in self._data_relations.items():
+            if not data:
+                # There is no data for these etype for this flush round.
+                continue
+            buf = pgstore._create_copyfrom_buffer(data, ('eid_from', 'eid_to'))
+            if not buf:
+                # The buffer is empty. This is probably due to error in _create_copyfrom_buffer
+                raise ValueError
+            cursor = self._cnx.cnxset.cu
+            # Push into the tmp table
+            cursor.copy_from(buf, '%s_relation_tmp' % rtype.lower(),
+                             null='NULL', columns=('eid_from', 'eid_to'))
+            # Clear data cache
+            self._data_relations[rtype] = []
+
+    def flush_entities(self):
+        """ Flush the entities data
+        """
+        for etype, data in self._data_entities.items():
+            if not data:
+                # There is no data for these etype for this flush round.
+                continue
+            # XXX It may be interresting to directly infer the columns'
+            # names from the schema instead of using .keys()
+            columns = data[0].keys()
+            # XXX For now, the _create_copyfrom_buffer does a "row[column]"
+            # which can lead to a key error.
+            # Thus we should create dictionary with all the keys.
+            columns = set()
+            for d in data:
+                columns.update(d.keys())
+            _data = []
+            _base_data = dict.fromkeys(columns)
+            for d in data:
+                _d = _base_data.copy()
+                _d.update(d)
+                _data.append(_d)
+            buf = pgstore._create_copyfrom_buffer(_data, columns)
+            if not buf:
+                # The buffer is empty. This is probably due to error in _create_copyfrom_buffer
+                raise ValueError('Error in buffer creation for etype %s' % etype)
+            columns = ['cw_%s' % attr for attr in columns]
+            cursor = self._cnx.cnxset.cu
+            try:
+                cursor.copy_from(buf, 'cw_%s' % etype.lower(), null='NULL', columns=columns)
+            except Exception as exc:
+                self.on_rollback(exc, etype, data)
+            # Clear data cache
+            self._data_entities[etype] = []
+        self.flush_meta_data()
+
+    def flush_meta_data(self):
+        """ Flush the meta data (entities table, is_instance table, ...)
+        """
+        if self.slave_mode:
+            raise RuntimeError('Flushing meta data is not allow in slave mode')
+        if not self._dbh.table_exists('cwmassive_initialized'):
+            self.logger.info('No information available for initialized etypes/rtypes')
+            return
+        if not self._metadata_table_created:
+            # Keep the correctly flush meta data in database
+            sql = "CREATE TABLE cwmassive_metadata (etype text)"
+            self.sql(sql)
+            self._metadata_table_created = True
+        crs = self.sql('SELECT etype FROM cwmassive_metadata')
+        already_flushed = set(e for e, in crs.fetchall())
+        crs = self.sql('SELECT retype FROM cwmassive_initialized WHERE type = %(t)s',
+                       {'t': 'etype'})
+        all_etypes = set(e for e, in crs.fetchall())
+        for etype in all_etypes:
+            if etype not in already_flushed:
+                # Deals with meta data
+                self.logger.info('Flushing meta data for %s' % etype)
+                self.insert_massive_meta_data(etype)
+                sql = 'INSERT INTO cwmassive_metadata VALUES (%(e)s)'
+                self.sql(sql, {'e': etype})
+
+    def _cleanup_entities(self, etype):
+        """ Cleanup etype table """
+        if self.eids_seq_range is None:
+            # Remove DEFAULT eids sequence if added
+            sql = 'ALTER TABLE cw_%s ALTER COLUMN cw_eid DROP DEFAULT;' % etype.lower()
+            self.sql(sql)
+        # Create indexes and constraints
+        tablename = SQL_PREFIX + etype.lower()
+        self.reapply_constraint_index(tablename)
+
+    def _cleanup_relations(self, rtype):
+        """ Cleanup rtype table """
+        # Push into relation table while removing duplicate
+        sql = '''INSERT INTO %(r)s_relation (eid_from, eid_to) SELECT DISTINCT
+                 T.eid_from, T.eid_to FROM %(r)s_relation_tmp AS T
+                 WHERE NOT EXISTS (SELECT 1 FROM %(r)s_relation AS TT WHERE
+                 TT.eid_from=T.eid_from AND TT.eid_to=T.eid_to);''' % {'r': rtype}
+        self.sql(sql)
+        # Drop temporary relation table
+        sql = ('DROP TABLE %(r)s_relation_tmp' % {'r': rtype.lower()})
+        self.sql(sql)
+        # Create indexes and constraints
+        tablename = '%s_relation' % rtype.lower()
+        self.reapply_constraint_index(tablename)
+
+    def insert_massive_meta_data(self, etype):
+        """ Massive insertion of meta data for a given etype, based on SQL statements.
+        """
+        # Push data - Use coalesce to avoid NULL (and get 0), if there is no
+        # entities of this type in the entities table.
+        # Meta data relations
+        self.metagen_push_relation(etype, self._cnx.user.eid, 'created_by_relation')
+        self.metagen_push_relation(etype, self._cnx.user.eid, 'owned_by_relation')
+        self.metagen_push_relation(etype, self.source.eid, 'cw_source_relation')
+        self.metagen_push_relation(etype, self._etype_eid_idx[etype], 'is_relation')
+        self.metagen_push_relation(etype, self._etype_eid_idx[etype], 'is_instance_of_relation')
+        sql = ("INSERT INTO entities (eid, type, asource, extid) "
+               "SELECT cw_eid, '%s', 'system', NULL FROM cw_%s "
+               "WHERE NOT EXISTS (SELECT 1 FROM entities WHERE eid=cw_eid)"
+               % (etype, etype.lower()))
+        self.sql(sql)
+
+    def metagen_push_relation(self, etype, eid_to, rtype):
+        sql = ("INSERT INTO %s (eid_from, eid_to) SELECT cw_eid, %s FROM cw_%s "
+               "WHERE NOT EXISTS (SELECT 1 FROM entities WHERE eid=cw_eid)"
+               % (rtype, eid_to, etype.lower()))
+        self.sql(sql)
+
+
+### CONSTRAINTS MANAGEMENT FUNCTIONS  ##########################################
+
+def get_size_constraints(schema):
+    """analyzes yams ``schema`` and returns the list of size constraints.
+
+    The returned value is a dictionary mapping entity types to a
+    sub-dictionnaries mapping attribute names -> max size.
+    """
+    size_constraints = {}
+    # iterates on all entity types
+    for eschema in schema.entities():
+        # for each entity type, iterates on attribute definitions
+        size_constraints[eschema.type] = eschema_constraints = {}
+        for rschema, aschema in eschema.attribute_definitions():
+            # for each attribute, if a size constraint is found,
+            # append it to the size constraint list
+            maxsize = None
+            rdef = rschema.rdef(eschema, aschema)
+            for constraint in rdef.constraints:
+                if isinstance(constraint, SizeConstraint):
+                    maxsize = constraint.max
+                    eschema_constraints[rschema.type] = maxsize
+    return size_constraints
+
+def get_default_values(schema):
+    """analyzes yams ``schema`` and returns the list of default values.
+
+    The returned value is a dictionary mapping entity types to a
+    sub-dictionnaries mapping attribute names -> default values.
+    """
+    default_values = {}
+    # iterates on all entity types
+    for eschema in schema.entities():
+        # for each entity type, iterates on attribute definitions
+        default_values[eschema.type] = eschema_constraints = {}
+        for rschema, _ in eschema.attribute_definitions():
+            # for each attribute, if a size constraint is found,
+            # append it to the size constraint list
+            if eschema.default(rschema.type) is not None:
+                eschema_constraints[rschema.type] = eschema.default(rschema.type)
+    return default_values
+
+
+class PGHelper(object):
+    def __init__(self, cnx, pg_schema='public'):
+        self.cnx = cnx
+        # Deals with pg schema, see #3216686
+        self.pg_schema = pg_schema
+
+    def application_indexes_constraints(self, tablename):
+        """ Get all the indexes/constraints for a given tablename """
+        indexes = self.application_indexes(tablename)
+        constraints = self.application_constraints(tablename)
+        _indexes = {}
+        for name, query in indexes.items():
+            # Remove pkey indexes (automatically created by constraints)
+            # Specific cases of primary key, see #3224079
+            if name not in constraints:
+                _indexes[name] = query
+        return _indexes, constraints
+
+    def table_exists(self, table_name):
+        sql = "SELECT * from information_schema.tables WHERE table_name=%(t)s AND table_schema=%(s)s"
+        crs = self.cnx.system_sql(sql, {'t': table_name, 's': self.pg_schema})
+        res = crs.fetchall()
+        if res:
+            return True
+        return False
+
+    # def check_if_primary_key_exists_for_table(self, table_name):
+    #     sql = ("SELECT constraint_name FROM information_schema.table_constraints "
+    #            "WHERE constraint_type = 'PRIMARY KEY' AND table_name=%(t)s AND table_schema=%(s)s")
+    #     crs = self.cnx.system_sql(sql, {'t': table_name, 's': self.pg_schema})
+    #     res = crs.fetchall()
+    #     if res:
+    #         return True
+    #     return False
+
+    def index_query(self, name):
+        """Get the request to be used to recreate the index"""
+        return self.cnx.system_sql("SELECT pg_get_indexdef(c.oid) "
+                                   "from pg_catalog.pg_class c "
+                                   "LEFT JOIN pg_catalog.pg_namespace n "
+                                   "ON n.oid = c.relnamespace "
+                                   "WHERE c.relname = %(r)s AND n.nspname=%(n)s",
+                                   {'r': name, 'n': self.pg_schema}).fetchone()[0]
+
+    def constraint_query(self, name):
+        """Get the request to be used to recreate the constraint"""
+        return self.cnx.system_sql("SELECT pg_get_constraintdef(c.oid) "
+                                   "from pg_catalog.pg_constraint c "
+                                   "LEFT JOIN pg_catalog.pg_namespace n "
+                                   "ON n.oid = c.connamespace "
+                                   "WHERE c.conname = %(r)s AND n.nspname=%(n)s",
+                                   {'r': name, 'n': self.pg_schema}).fetchone()[0]
+
+    def application_indexes(self, tablename):
+        """ Iterate over all the indexes """
+        # This SQL query (cf http://www.postgresql.org/message-id/432F450F.4080700@squiz.net)
+        # aims at getting all the indexes for each table.
+        sql = '''SELECT c.relname as "Name"
+        FROM pg_catalog.pg_class c
+        JOIN pg_catalog.pg_index i ON i.indexrelid = c.oid
+        JOIN pg_catalog.pg_class c2 ON i.indrelid = c2.oid
+        LEFT JOIN pg_catalog.pg_user u ON u.usesysid = c.relowner
+        LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
+        WHERE c.relkind IN ('i','')
+        AND c2.relname = '%s'
+        AND n.nspname NOT IN ('pg_catalog', 'pg_toast')
+        AND pg_catalog.pg_table_is_visible(c.oid);''' % tablename
+        indexes_list = self.cnx.system_sql(sql).fetchall()
+        indexes = {}
+        for name, in indexes_list:
+            indexes[name] = self.index_query(name)
+        return indexes
+
+    def application_constraints(self, tablename):
+        """ Iterate over all the constraints """
+        sql = '''SELECT i.conname as "Name"
+                 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_constraint i
+                 ON i.conrelid = c.oid JOIN pg_catalog.pg_class c2 ON i.conrelid=c2.oid
+                 LEFT JOIN pg_catalog.pg_user u ON u.usesysid = c.relowner
+                 LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
+                 WHERE c2.relname = '%s' AND n.nspname NOT IN ('pg_catalog', 'pg_toast')
+                 AND pg_catalog.pg_table_is_visible(c.oid);''' % tablename
+        indexes_list = self.cnx.system_sql(sql).fetchall()
+        constraints = {}
+        for name, in indexes_list:
+            query = self.constraint_query(name)
+            constraints[name] = 'ALTER TABLE %s ADD CONSTRAINT %s %s' % (tablename, name, query)
+        return constraints
--- a/dataimport/pgstore.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/dataimport/pgstore.py	Thu Dec 10 12:34:15 2015 +0100
@@ -16,18 +16,22 @@
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """Postgres specific store"""
+from __future__ import print_function
 
 import threading
 import warnings
-import cPickle
 import os.path as osp
-from StringIO import StringIO
+from io import StringIO
 from time import asctime
 from datetime import date, datetime, time
 from collections import defaultdict
 from base64 import b64encode
 
+from six import string_types, integer_types, text_type
+from six.moves import cPickle as pickle, range
+
 from cubicweb.utils import make_uid
+from cubicweb.server.utils import eschema_eid
 from cubicweb.server.sqlutils import SQL_PREFIX
 from cubicweb.dataimport.stores import NoHookRQLObjectStore
 
@@ -40,7 +44,7 @@
     try:
         chunksize = (len(statements) / nb_threads) + 1
         threads = []
-        for i in xrange(nb_threads):
+        for i in range(nb_threads):
             chunks = statements[i*chunksize:(i+1)*chunksize]
             thread = threading.Thread(target=_execmany_thread,
                                       args=(sql_connect, chunks,
@@ -52,7 +56,7 @@
         for t in threads:
             t.join()
     except Exception:
-        print 'Error in import statements'
+        print('Error in import statements')
 
 def _execmany_thread_not_copy_from(cu, statement, data, table=None,
                                    columns=None, encoding='utf-8'):
@@ -69,9 +73,9 @@
         _execmany_thread_not_copy_from(cu, statement, data)
     else:
         if columns is None:
-            cu.copy_from(buf, table, null='NULL')
+            cu.copy_from(buf, table, null=u'NULL')
         else:
-            cu.copy_from(buf, table, null='NULL', columns=columns)
+            cu.copy_from(buf, table, null=u'NULL', columns=columns)
 
 def _execmany_thread(sql_connect, statements, dump_output_dir=None,
                      support_copy_from=True, encoding='utf-8'):
@@ -100,7 +104,7 @@
                     columns = list(data[0])
                 execmany_func(cu, statement, data, table, columns, encoding)
             except Exception:
-                print 'unable to copy data into table %s' % table
+                print('unable to copy data into table %s' % table)
                 # Error in import statement, save data in dump_output_dir
                 if dump_output_dir is not None:
                     pdata = {'data': data, 'statement': statement,
@@ -108,11 +112,10 @@
                     filename = make_uid()
                     try:
                         with open(osp.join(dump_output_dir,
-                                           '%s.pickle' % filename), 'w') as fobj:
-                            fobj.write(cPickle.dumps(pdata))
+                                           '%s.pickle' % filename), 'wb') as fobj:
+                            pickle.dump(pdata, fobj)
                     except IOError:
-                        print 'ERROR while pickling in', dump_output_dir, filename+'.pickle'
-                        pass
+                        print('ERROR while pickling in', dump_output_dir, filename+'.pickle')
                 cnx.rollback()
                 raise
     finally:
@@ -122,50 +125,44 @@
 
 def _copyfrom_buffer_convert_None(value, **opts):
     '''Convert None value to "NULL"'''
-    return 'NULL'
+    return u'NULL'
 
 def _copyfrom_buffer_convert_number(value, **opts):
     '''Convert a number into its string representation'''
-    return str(value)
+    return text_type(value)
 
 def _copyfrom_buffer_convert_string(value, **opts):
     '''Convert string value.
-
-    Recognized keywords:
-    :encoding: resulting string encoding (default: utf-8)
     '''
-    encoding = opts.get('encoding','utf-8')
-    escape_chars = ((u'\\', ur'\\'), (u'\t', u'\\t'), (u'\r', u'\\r'),
+    escape_chars = ((u'\\', u'\\\\'), (u'\t', u'\\t'), (u'\r', u'\\r'),
                     (u'\n', u'\\n'))
     for char, replace in escape_chars:
         value = value.replace(char, replace)
-    if isinstance(value, unicode):
-        value = value.encode(encoding)
     return value
 
 def _copyfrom_buffer_convert_date(value, **opts):
     '''Convert date into "YYYY-MM-DD"'''
     # Do not use strftime, as it yields issue with date < 1900
     # (http://bugs.python.org/issue1777412)
-    return '%04d-%02d-%02d' % (value.year, value.month, value.day)
+    return u'%04d-%02d-%02d' % (value.year, value.month, value.day)
 
 def _copyfrom_buffer_convert_datetime(value, **opts):
     '''Convert date into "YYYY-MM-DD HH:MM:SS.UUUUUU"'''
     # Do not use strftime, as it yields issue with date < 1900
     # (http://bugs.python.org/issue1777412)
-    return '%s %s' % (_copyfrom_buffer_convert_date(value, **opts),
-                      _copyfrom_buffer_convert_time(value, **opts))
+    return u'%s %s' % (_copyfrom_buffer_convert_date(value, **opts),
+                       _copyfrom_buffer_convert_time(value, **opts))
 
 def _copyfrom_buffer_convert_time(value, **opts):
     '''Convert time into "HH:MM:SS.UUUUUU"'''
-    return '%02d:%02d:%02d.%06d' % (value.hour, value.minute,
-                                    value.second, value.microsecond)
+    return u'%02d:%02d:%02d.%06d' % (value.hour, value.minute,
+                                     value.second, value.microsecond)
 
 # (types, converter) list.
 _COPYFROM_BUFFER_CONVERTERS = [
     (type(None), _copyfrom_buffer_convert_None),
-    ((long, int, float), _copyfrom_buffer_convert_number),
-    (basestring, _copyfrom_buffer_convert_string),
+    (integer_types + (float,), _copyfrom_buffer_convert_number),
+    (string_types, _copyfrom_buffer_convert_string),
     (datetime, _copyfrom_buffer_convert_datetime),
     (date, _copyfrom_buffer_convert_date),
     (time, _copyfrom_buffer_convert_time),
@@ -185,7 +182,7 @@
     rows = []
     if columns is None:
         if isinstance(data[0], (tuple, list)):
-            columns = range(len(data[0]))
+            columns = list(range(len(data[0])))
         elif isinstance(data[0], dict):
             columns = data[0].keys()
         else:
@@ -209,6 +206,7 @@
             for types, converter in _COPYFROM_BUFFER_CONVERTERS:
                 if isinstance(value, types):
                     value = converter(value, **convert_opts)
+                    assert isinstance(value, text_type)
                     break
             else:
                 raise ValueError("Unsupported value type %s" % type(value))
@@ -335,7 +333,7 @@
         self._sql.eid_insertdicts = {}
 
     def flush(self):
-        print 'starting flush'
+        print('starting flush')
         _entities_sql = self._sql.entities
         _relations_sql = self._sql.relations
         _inlined_relations_sql = self._sql.inlined_relations
@@ -346,7 +344,7 @@
             # In that case, simply update the insert dict and remove
             # the need to make the
             # UPDATE statement
-            for statement, datalist in _inlined_relations_sql.iteritems():
+            for statement, datalist in _inlined_relations_sql.items():
                 new_datalist = []
                 # for a given inlined relation,
                 # browse each couple to be inserted
@@ -410,7 +408,7 @@
             _sql[statement] = [data]
 
     def add_entity(self, cnx, entity):
-        with self._storage_handler(entity, 'added'):
+        with self._storage_handler(cnx, entity, 'added'):
             attrs = self.preprocess_entity(entity)
             rtypes = self._inlined_rtypes_cache.get(entity.cw_etype, ())
             if isinstance(rtypes, str):
--- a/dataimport/stores.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/dataimport/stores.py	Thu Dec 10 12:34:15 2015 +0100
@@ -21,7 +21,7 @@
 
     >>> user_eid = store.prepare_insert_entity('CWUser', login=u'johndoe')
     >>> group_eid = store.prepare_insert_entity('CWUser', name=u'unknown')
-    >>> store.relate(user_eid, 'in_group', group_eid)
+    >>> store.prepare_insert_relation(user_eid, 'in_group', group_eid)
     >>> store.flush()
     >>> store.commit()
     >>> store.finish()
@@ -61,6 +61,8 @@
 from datetime import datetime
 from copy import copy
 
+from six import text_type
+
 from logilab.common.deprecation import deprecated
 from logilab.common.decorators import cached
 
@@ -101,7 +103,7 @@
         and inlined relations.
         """
         entity = self._cnx.entity_from_eid(eid)
-        assert entity.cw_etype == etype, 'Trying to update with wrong type {}'.format(etype)
+        assert entity.cw_etype == etype, 'Trying to update with wrong type %s' % etype
         # XXX some inlined relations may already exists
         entity.cw_set(**kwargs)
 
@@ -120,6 +122,10 @@
         """Commit the database transaction."""
         return self._commit()
 
+    def finish(self):
+        """Nothing to do once import is terminated for this store."""
+        pass
+
     @property
     def session(self):
         warnings.warn('[3.19] deprecated property.', DeprecationWarning, stacklevel=2)
@@ -168,7 +174,7 @@
         """Given an entity type, attributes and inlined relations, returns the inserted entity's
         eid.
         """
-        for k, v in kwargs.iteritems():
+        for k, v in kwargs.items():
             kwargs[k] = getattr(v, 'eid', v)
         entity, rels = self.metagen.base_etype_dicts(etype)
         # make a copy to keep cached entity pristine
@@ -183,7 +189,7 @@
         kwargs = dict()
         if inspect.getargspec(self.add_relation).keywords:
             kwargs['subjtype'] = entity.cw_etype
-        for rtype, targeteids in rels.iteritems():
+        for rtype, targeteids in rels.items():
             # targeteids may be a single eid or a list of eids
             inlined = self.rschema(rtype).inlined
             try:
@@ -298,7 +304,7 @@
             genfunc = self.generate(attr)
             if genfunc:
                 entity.cw_edited.edited_attribute(attr, genfunc(entity))
-        if isinstance(extid, unicode):
+        if isinstance(extid, text_type):
             extid = extid.encode('utf-8')
         return self.source, extid
 
@@ -320,4 +326,3 @@
 
     def gen_owned_by(self, entity):
         return self._cnx.user.eid
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dataimport/test/data-massimport/schema.py	Thu Dec 10 12:34:15 2015 +0100
@@ -0,0 +1,154 @@
+# copyright 2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# contact http://www.logilab.fr -- mailto:contact@logilab.fr
+#
+# This program 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 2.1 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 Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+
+"""cubicweb-geonames schema"""
+
+from yams.buildobjs import (EntityType, RelationDefinition, SubjectRelation,
+			    String, Int, BigInt, Float, Date)
+from cubicweb.schemas.base import ExternalUri
+
+"""
+See geonames readme.txt for more details.
+"""
+
+class TestLocation(EntityType):
+    """
+    Entity type for location of Geonames.
+    See cities1000.zip, cities5000.zip, cities15000.zip and allCountries.txt
+    """
+    name = String(maxsize=1024, indexed=True, fulltextindexed=True)
+    geonameid = Int(required=True, unique=True, indexed=True)
+
+class Location(EntityType):
+    """
+    Entity type for location of Geonames.
+    See cities1000.zip, cities5000.zip, cities15000.zip and allCountries.txt
+    """
+    name = String(maxsize=1024, indexed=True, fulltextindexed=True)
+    geonameid = Int(indexed=True)
+    asciiname = String(maxsize=200, fulltextindexed=True)
+    alternatenames = String(fulltextindexed=True)
+    names = SubjectRelation('LocationName', cardinality='**')
+    latitude = Float(indexed=True)
+    longitude = Float(indexed=True)
+    feature_class = String(maxsize=1, indexed=True)
+    feature_code = SubjectRelation('FeatureCode', cardinality='?*', inlined=True)
+    country = SubjectRelation('Country', cardinality='?*', inlined=True)
+    alternate_country_code = String(maxsize=60)
+    main_administrative_region = SubjectRelation('AdministrativeRegion', cardinality='?*', inlined=True)
+    second_administrative_region = SubjectRelation('AdministrativeRegion', cardinality='?*', inlined=True)
+    admin_code_1 = String(maxsize=124)
+    admin_code_2 = String(maxsize=124)
+    admin_code_3 = String(maxsize=20)
+    admin_code_4 = String(maxsize=20)
+    population = BigInt(indexed=True)
+    elevation = Int(indexed=True)
+    gtopo30 = Int(indexed=True)
+    timezone = SubjectRelation('TimeZone', cardinality='?*', inlined=True)
+    geonames_date = Date()
+
+class LocationName(EntityType):
+    """
+    Name of a Location
+    """
+    name = String(maxsize=1024, indexed=True, fulltextindexed=True)
+    language = SubjectRelation('Language', cardinality='?*', inlined=True)
+    alternatenamesid = Int(indexed=True)
+
+class FeatureCode(EntityType):
+    """
+    Entity type for feature codes of Geonames.
+    See featureCodes_en.txt
+    """
+    name = String(maxsize=1024, indexed=True, fulltextindexed=True)
+    main_code = String(maxsize=1, indexed=True)
+    code = String(maxsize=12)
+    description = String(maxsize=1024, fulltextindexed=True)
+
+class AdministrativeRegion(EntityType):
+    """
+    Entity type for administrative regions of Geonames.
+    See admin1CodesASCII.txt and admin2Codes.txt
+    """
+    name = String(maxsize=1024, indexed=True, fulltextindexed=True)
+    code = String(maxsize=64, indexed=True)
+    country = SubjectRelation('Country', cardinality='?*', inlined=True)
+    geonameid = Int(indexed=True)
+    asciiname = String(maxsize=200, fulltextindexed=True)
+
+class Language(EntityType):
+    """
+    Entity type for languages of Geonames.
+    See admin1CodesASCII.txt and admin2Codes.txt
+    """
+    name = String(maxsize=1024, indexed=True, fulltextindexed=True)
+    iso_639_3 = String(maxsize=3, indexed=True)
+    iso_639_2 = String(maxsize=64, indexed=True)
+    iso_639_1 = String(maxsize=3, indexed=True)
+
+class Continent(EntityType):
+    """
+    Entity type for continents of geonames.
+    """
+    name = String(maxsize=1024, indexed=True, fulltextindexed=True)
+    code = String(maxsize=2, indexed=True)
+    geonameid = Int(indexed=True)
+
+class Country(EntityType):
+    """
+    Entity type for countries of geonames.
+    See countryInfo.txt
+    """
+    name = String(maxsize=1024, indexed=True, fulltextindexed=True)
+    code = String(maxsize=2, indexed=True)
+    code3 = String(maxsize=3, indexed=True)
+    codenum = Int(indexed=True)
+    fips = String(maxsize=2)
+    capital = String(maxsize=1024, fulltextindexed=True)
+    area = Float(indexed=True)
+    population = BigInt(indexed=True)
+    continent_code = String(maxsize=3)
+    continent = SubjectRelation('Continent', cardinality='?*', inlined=True)
+    tld = String(maxsize=64)
+    currency = String(maxsize=1024, fulltextindexed=True)
+    currency_code = String(maxsize=64)
+    geonameid = Int(indexed=True)
+    phone = String(maxsize=64)
+    postal_code = String(maxsize=200)
+    postal_code_regex = String(maxsize=200)
+    languages_code = String(maxsize=200)
+    neighbours_code = String(maxsize=200)
+    equivalent_fips = String(maxsize=2)
+
+class TimeZone(EntityType):
+    """
+    Entity type for timezone of geonames.
+    See timeZones.txt
+    """
+    code = String(maxsize=1024, indexed=True)
+    gmt = Float()
+    dst = Float()
+    raw_offset = Float()
+
+class used_language(RelationDefinition):
+    subject = 'Country'
+    object = 'Language'
+    cardinality = '**'
+
+class neighbour_of(RelationDefinition):
+    subject = 'Country'
+    object = 'Country'
+    cardinality = '**'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dataimport/test/data/geonames.csv	Thu Dec 10 12:34:15 2015 +0100
@@ -0,0 +1,4000 @@
+3038814	Costa de Xurius	Costa de Xurius		42.5	1.48333	T	SLP	AD		00				0		1316	Europe/Andorra	1993-12-23
+3038815	Font de la Xona	Font de la Xona		42.55003	1.44986	H	SPNG	AD		04				0		2082	Europe/Andorra	2010-01-11
+3038816	Xixerella	Xixerella		42.55327	1.48736	P	PPL	AD		04				0		1520	Europe/Andorra	2009-04-24
+3038817	Xixerella	Xixerella	Xixerella	42.55	1.48333	A	ADMD	AD		00				0		1548	Europe/Andorra	2011-11-05
+3038818	Riu Xic	Riu Xic		42.56667	1.68333	H	STM	AD		00				0		2340	Europe/Andorra	1993-12-23
+3038819	Pas del Xic	Pas del Xic		42.5	1.58333	R	TRL	AD		00				0		1888	Europe/Andorra	1993-12-23
+3038820	Roc del Xeig	Roc del Xeig		42.56667	1.48333	T	RK	AD		00				0		1508	Europe/Andorra	1993-12-23
+3038821	Collada del Xeig	Collada del Xeig		42.56667	1.48333	T	PK	AD		00				0		1508	Europe/Andorra	1993-12-23
+3038822	Fonts Vives	Fonts Vives		42.5	1.56667	H	SPNG	AD		00				0		1776	Europe/Andorra	1993-12-23
+3038823	Roc de Vista	Roc de Vista		42.5	1.48333	T	RK	AD		00				0		1316	Europe/Andorra	1993-12-23
+3038824	Obaga de Vista	Obaga de Vista		42.48333	1.45	T	SLP	AD		00				0		1195	Europe/Andorra	1993-12-23
+3038825	Coll de Vista	Coll de Vista		42.46667	1.58333	T	SPUR	AD		00				0		2367	Europe/Andorra	1993-12-23
+3038826	Coll de Vista	Coll de Vista	Coll de Vista	42.48333	1.43333	T	PASS	AD		00				0		1938	Europe/Andorra	2011-11-05
+3038827	Visanseny	Visanseny	Visanceny,Visanseny	42.56667	1.61667	L	LCTY	AD	AD	00				0		1920	Europe/Andorra	2011-11-05
+3038828	Roc de la Vinya	Roc de la Vinya		42.53333	1.56667	T	RK	AD		00				0		1418	Europe/Andorra	1993-12-23
+3038829	Canal de la Vinya	Canal de la Vinya		42.51667	1.51667	H	STM	AD		00				0		1265	Europe/Andorra	1993-12-23
+3038830	Bosc de Villar	Bosc de Villar		42.6	1.55	V	FRST	AD		00				0		2298	Europe/Andorra	1993-12-23
+3038831	Torrent de Vila	Torrent de Vila		42.53333	1.56667	H	STM	AD		00				0		1418	Europe/Andorra	1993-12-23
+3038832	Vila	Vila	Casas Vila,Vila	42.53222	1.57392	P	PPL	AD		03				0		1418	Europe/Andorra	2011-11-05
+3038833	Basers de Vicenç	Basers de Vicenc		42.48333	1.48333	T	CLF	AD		00				0		981	Europe/Andorra	1993-12-23
+3038834	Pla de Viàs	Pla de Vias		42.58333	1.66667	T	UPLD	AD		00				0		2159	Europe/Andorra	1993-12-23
+3038835	Vial del Cardaire	Vial del Cardaire		42.56667	1.5	L	LCTY	AD		00				0		1636	Europe/Andorra	1993-12-23
+3038836	Font del Vi	Font del Vi		42.51667	1.48333	H	SPNG	AD		00				0		1839	Europe/Andorra	1993-12-23
+3038837	Font Verda	Font Verda		42.55	1.56667	H	SPNG	AD		00				0		1828	Europe/Andorra	1993-12-23
+3038838	Costa Verda	Costa Verda		42.48333	1.66667	T	SLP	AD		00				0		2524	Europe/Andorra	1993-12-23
+3038839	Costa Verda	Costa Verda		42.48333	1.56667	T	SLP	AD		00				0		2231	Europe/Andorra	1993-12-23
+3038840	Serrat de Ventader	Serrat de Ventader		42.48333	1.43333	T	MT	AD		00				0		1938	Europe/Andorra	1993-12-23
+3038841	Bony de Vellatocina	Bony de Vellatocina		42.61667	1.5	T	PK	AD		00				0		2390	Europe/Andorra	1993-12-23
+3038842	Pleta Vella	Pleta Vella		42.51667	1.61667	L	GRAZ	AD		00				0		2254	Europe/Andorra	1993-12-23
+3038843	Solà Vell	Sola Vell		42.46667	1.48333	T	SLP	AD		00				0		1134	Europe/Andorra	1993-12-23
+3038844	Port Vell	Port Vell		42.65	1.55	T	PASS	AD		00				0		2181	Europe/Andorra	1993-12-23
+3038845	Port Negre del Pallars	Port Negre del Pallars	Port Negre del Pallars,Port Vell	42.56667	1.45	T	PASS	AD		00				0		2137	Europe/Andorra	2011-11-05
+3038846	Bancal Vedeller	Bancal Vedeller		42.6	1.46667	R	TRL	AD		00				0		2421	Europe/Andorra	1993-12-23
+3038847	Vedat del Xeig	Vedat del Xeig		42.56667	1.48333	L	LCTY	AD		00				0		1508	Europe/Andorra	1993-12-23
+3038848	Vedat dels Plans	Vedat dels Plans		42.53333	1.5	A	ADMD	AD		00				0		1357	Europe/Andorra	1993-12-23
+3038849	Vedat de Coll de les Cases	Vedat de Coll de les Cases		42.56667	1.5	L	LCTY	AD		00				0		1636	Europe/Andorra	1993-12-23
+3038850	Serra del Vedat	Serra del Vedat		42.46667	1.48333	T	RDGE	AD		00				0		1134	Europe/Andorra	1993-12-23
+3038851	Planades del Vedat	Planades del Vedat		42.53333	1.5	T	UPLD	AD		00				0		1357	Europe/Andorra	1993-12-23
+3038852	Veda de Sorteny	Veda de Sorteny		42.61667	1.55	L	LCTY	AD		00				0		2007	Europe/Andorra	1993-12-23
+3038853	Veda del Castellar	Veda del Castellar		42.63333	1.51667	A	ADMD	AD		00				0		1894	Europe/Andorra	1993-12-23
+3038854	Canal de les Veces	Canal de les Veces		42.51667	1.51667	H	STM	AD		00				0		1265	Europe/Andorra	1993-12-23
+3038855	Coma de Varilles	Coma de Varilles		42.63333	1.53333	T	VAL	AD		00				0		2072	Europe/Andorra	1993-12-23
+3038856	Portella de les Vaques	Portella de les Vaques		42.56667	1.45	T	PASS	AD		00				0		2137	Europe/Andorra	1993-12-23
+3038857	Pas de les Vaques	Pas de les Vaques		42.58333	1.7	T	PASS	AD		00				0		2584	Europe/Andorra	1993-12-23
+3038858	Collada de les Vaques	Collada de les Vaques		42.56667	1.56667	T	PASS	AD		00				0		2089	Europe/Andorra	1993-12-23
+3038859	Roc del Vaquer	Roc del Vaquer		42.63333	1.48333	T	CLF	AD		00				0		2283	Europe/Andorra	1993-12-23
+3038860	Valls de la Coma	Valls de la Coma		42.6	1.63333	L	LCTY	AD		00				0		1893	Europe/Andorra	1993-12-23
+3038861	Vall d'Incles	Vall d'Incles		42.58386	1.66331	L	LCTY	AD		02				0		1867	Europe/Andorra	2010-01-11
+3038862	Vall de Soldeu	Vall de Soldeu		42.55	1.68333	L	LCTY	AD		00				0		2254	Europe/Andorra	1993-12-23
+3038863	Riu de la Vall del Riu	Riu de la Vall del Riu		42.56667	1.61667	H	STM	AD		00				0		1920	Europe/Andorra	1993-12-23
+3038864	Estany Gran de la Vall del Riu	Estany Gran de la Vall del Riu		42.601	1.59368	H	LK	AD		00				0		2467	Europe/Andorra	2011-04-19
+3038865	Cascada de la Vall del Riu	Cascada de la Vall del Riu		42.56667	1.61667	H	FLLS	AD		00				0		1920	Europe/Andorra	1993-12-23
+3038866	Canals de la Vall del Riu	Canals de la Vall del Riu		42.58333	1.6	H	RVN	AD		00				0		1828	Europe/Andorra	1993-12-23
+3038867	Camí de la Vall del Riu	Cami de la Vall del Riu		42.58333	1.61667	R	TRL	AD		00				0		1707	Europe/Andorra	1993-12-23
+3038868	Bosc de la Vall del Riu	Bosc de la Vall del Riu		42.58333	1.61667	V	FRST	AD		00				0		1707	Europe/Andorra	1993-12-23
+3038869	Vall del Riu	Vall del Riu		42.6	1.6	A	ADMD	AD		00				0		2143	Europe/Andorra	1993-12-23
+3038870	Coll de Vall Civera	Coll de Vall Civera	Coll de Valcibera,Coll de Vall Civera,Collado de Vall-Civera,Port de Vall Civera	42.48333	1.66667	T	PASS	AD		00				0		2524	Europe/Andorra	2011-11-05
+3038871	Obac de la Vall	Obac de la Vall		42.46667	1.5	T	SLP	AD		00				0		1383	Europe/Andorra	1993-12-23
+3038872	Riu Valira d’Orient	Riu Valira d'Orient	Rio Balira del Orien,Riu Valira d'Orient,Riu Valira d’Orient,Río Balira del Orien	42.51667	1.53333	H	STM	AD		00				0		1460	Europe/Andorra	2011-11-05
+3038873	Riu Valira del Nord	Riu Valira del Nord	Riu Valira d'Ordino,Riu Valira del Nord,Riu Valira del Nort,Riu Valira d’Ordino,Valira del Nord,Valira del Norte	42.34645	1.44271	H	STM	AD		00				0		682	Europe/Andorra	2011-11-05
+3038874	Estanys de la Val del Riu	Estanys de la Val del Riu		42.60138	1.59418	H	LKS	AD		00				0		2467	Europe/Andorra	2011-04-19
+3038875	Vaca Morta	Vaca Morta		42.56667	1.76667	L	LCTY	AD		00				0		1674	Europe/Andorra	1993-12-23
+3038876	Riu d’ Urina	Riu d' Urina		42.56667	1.58333	H	STM	AD		00				0		1919	Europe/Andorra	1993-12-23
+3038877	Serrat de la Uïna	Serrat de la Uina		42.56667	1.51667	T	RDGE	AD		00				0		1500	Europe/Andorra	1993-12-23
+3038878	Obaga de la Tuta	Obaga de la Tuta		42.48333	1.45	T	SLP	AD		00				0		1195	Europe/Andorra	1993-12-23
+3038879	Cova de la Tuta	Cova de la Tuta		42.48333	1.45	S	CAVE	AD		00				0		1195	Europe/Andorra	1993-12-23
+3038880	Roca del Tut	Roca del Tut		42.55	1.46667	T	RK	AD		00				0		1585	Europe/Andorra	1993-12-23
+3038881	Coll de Turer	Coll de Turer		42.56667	1.46667	T	PK	AD		00				0		1673	Europe/Andorra	1993-12-23
+3038882	Font del Tudó	Font del Tudo		42.43333	1.53333	H	SPNG	AD		00				0		2108	Europe/Andorra	1993-12-23
+3038883	Estany de les Truites	Estany de les Truites		42.58333	1.45	H	LK	AD		00				0		2156	Europe/Andorra	1993-12-23
+3038884	Serra de Tristaina	Serra de Tristaina	Serra de Tristaina	42.65	1.48333	T	RDGE	AD		00				0		2341	Europe/Andorra	2011-11-05
+3038885	Riu de Tristaina	Riu de Tristaina		42.61667	1.55	H	STM	AD		00				0		2007	Europe/Andorra	1993-12-23
+3038886	Pic de Tristaina	Pic de Tristaina	Pic de Triatagne,Pic de Tristagne,Pic de Tristaina,Pic des Tri-Stagnes,Tristaina	42.65265	1.49242	T	PK	AD	AD,FR	00				0		2384	Europe/Andorra	2007-04-29
+3038887	Clot de Tres Torrents	Clot de Tres Torrents		42.53333	1.53333	H	RVN	AD		00				0		1521	Europe/Andorra	1993-12-23
+3038888	Bony de Tres Corts	Bony de Tres Corts		42.53333	1.53333	T	SPUR	AD		00				0		1521	Europe/Andorra	1993-12-23
+3038889	Canal dels Trèmols	Canal dels Tremols		42.5	1.48333	H	STM	AD		00				0		1316	Europe/Andorra	1993-12-23
+3038890	Travenc	Travenc		42.6	1.68333	L	LCTY	AD		00				0		2089	Europe/Andorra	1993-12-23
+3038891	Pleta de la Trava	Pleta de la Trava		42.48333	1.61667	L	GRAZ	AD		00				0		2217	Europe/Andorra	1993-12-23
+3038892	Coll de la Trava	Coll de la Trava		42.48333	1.46667	T	SPUR	AD		00				0		1148	Europe/Andorra	1993-12-23
+3038893	Canal de la Trava	Canal de la Trava		42.56667	1.53333	H	RVN	AD		00				0		1669	Europe/Andorra	1993-12-23
+3038894	Bosc de la Trava	Bosc de la Trava		42.48333	1.63333	V	FRST	AD		00				0		2296	Europe/Andorra	1993-12-23
+3038895	Font dels Traginers	Font dels Traginers		42.43333	1.51667	H	SPNG	AD		00				0		2031	Europe/Andorra	1993-12-23
+3038896	Pla de les Toves	Pla de les Toves		42.46667	1.45	T	UPLD	AD		00				0		1562	Europe/Andorra	1993-12-23
+3038897	Torrent del Tossalroi	Torrent del Tossalroi		42.46667	1.51667	H	STM	AD		00				0		1985	Europe/Andorra	1993-12-23
+3038898	Tossal Gran	Tossal Gran		42.48333	1.48333	L	LCTY	AD		00				0		981	Europe/Andorra	1993-12-23
+3038899	Tossalet i Vinyals	Tossalet i Vinyals		42.48333	1.48333	L	LCTY	AD		00				0		981	Europe/Andorra	1993-12-23
+3038900	Bosc del Tossal de les Poselles	Bosc del Tossal de les Poselles		42.53333	1.5	V	FRST	AD		00				0		1357	Europe/Andorra	1993-12-23
+3038901	Tossal	Tossal		42.46667	1.48333	L	LCTY	AD		00				0		1134	Europe/Andorra	1993-12-23
+3038902	Tosquers	Tosquers		42.56667	1.48333	T	SLP	AD		00				0		1508	Europe/Andorra	1993-12-23
+3038903	Canal del Tosquer	Canal del Tosquer		42.56667	1.51667	H	STM	AD		00				0		1500	Europe/Andorra	1993-12-23
+3038904	Bosc del Tosquer	Bosc del Tosquer		42.56667	1.53333	V	FRST	AD		00				0		1669	Europe/Andorra	1993-12-23
+3038905	Bosc del Tosquer	Bosc del Tosquer		42.53333	1.6	V	FRST	AD		00				0		1888	Europe/Andorra	1993-12-23
+3038906	Bosc de la Tosca	Bosc de la Tosca		42.43333	1.45	V	FRST	AD		00				0		877	Europe/Andorra	1993-12-23
+3038907	Tosa d’Incles	Tosa d'Incles		42.58333	1.68333	A	ADMD	AD		00				0		2294	Europe/Andorra	1993-12-23
+3038908	Cap de Tosa d’Entor	Cap de Tosa d'Entor		42.6	1.65	T	PK	AD		00				0		2131	Europe/Andorra	1993-12-23
+3038909	Tosa de les Mussoles	Tosa de les Mussoles		42.61667	1.68333	L	LCTY	AD		00				0		2406	Europe/Andorra	1993-12-23
+3038910	Pic de la Tosa de Juclar	Pic de la Tosa de Juclar		42.6	1.71667	T	PK	AD		00				0		2516	Europe/Andorra	1993-12-23
+3038911	Collada de la Tosa de Caraup	Collada de la Tosa de Caraup		42.6	1.65	T	SPUR	AD		00				0		2131	Europe/Andorra	1993-12-23
+3038912	Planell de la Tosa	Planell de la Tosa		42.53333	1.45	T	UPLD	AD		00				0		2130	Europe/Andorra	1993-12-23
+3038913	Canals de la Tosa	Canals de la Tosa		42.58333	1.7	H	RVN	AD		00				0		2584	Europe/Andorra	1993-12-23
+3038914	Canal de la Tosa	Canal de la Tosa		42.5	1.56667	H	STM	AD		00				0		1776	Europe/Andorra	1993-12-23
+3038915	Bosc de la Tosa	Bosc de la Tosa		42.55	1.58333	V	FRST	AD		00				0		1499	Europe/Andorra	1993-12-23
+3038916	Canal Torta	Canal Torta		42.56667	1.51667	H	STM	AD		00				0		1500	Europe/Andorra	1993-12-23
+3038917	Canal Torta	Canal Torta		42.53333	1.53333	H	STM	AD		00				0		1521	Europe/Andorra	1993-12-23
+3038918	Torrent Tort	Torrent Tort		42.53333	1.58333	H	STM	AD		00				0		1571	Europe/Andorra	1993-12-23
+3038919	Torretinyà	Torretinya		42.45	1.51667	L	LCTY	AD		00				0		1790	Europe/Andorra	1993-12-23
+3038920	Prat d’en Torres	Prat d'en Torres		42.6	1.51667	L	GRAZ	AD		00				0		1445	Europe/Andorra	1993-12-23
+3038921	Canals de Torrent Pregó	Canals de Torrent Prego		42.48333	1.48333	H	STM	AD		00				0		981	Europe/Andorra	1993-12-23
+3038922	Canal de Torrentinyà	Canal de Torrentinya		42.45	1.5	H	STM	AD		00				0		1614	Europe/Andorra	1993-12-23
+3038923	Torrentill	Torrentill		42.46667	1.5	H	STM	AD		00				0		1383	Europe/Andorra	1993-12-23
+3038924	Camí de Torrent Forcat	Cami de Torrent Forcat		42.46667	1.51667	R	TRL	AD		00				0		1985	Europe/Andorra	1993-12-23
+3038925	Canal del Torrent Cauber	Canal del Torrent Cauber		42.6	1.51667	H	RVN	AD		00				0		1445	Europe/Andorra	1993-12-23
+3038926	Torre dels Soldats	Torre dels Soldats	Pic Monturull,Torre dels Soldats	42.45	1.58333	T	PK	AD		00				0		2537	Europe/Andorra	2011-11-05
+3038927	Torrapuis	Torrapuis		42.53333	1.53333	L	LCTY	AD		00				0		1521	Europe/Andorra	1993-12-23
+3038928	Pic de Torradella	Pic de Torradella		42.6	1.61667	T	PK	AD		00				0		2271	Europe/Andorra	1993-12-23
+3038929	Pala de la Torradella	Pala de la Torradella		42.58333	1.61667	T	SLP	AD		00				0		1707	Europe/Andorra	1993-12-23
+3038930	Obaga de Torradella	Obaga de Torradella		42.6	1.63333	T	SLP	AD		00				0		1893	Europe/Andorra	1993-12-23
+3038931	Canals de Torradella	Canals de Torradella		42.6	1.63333	H	STM	AD		00				0		1893	Europe/Andorra	1993-12-23
+3038932	Borda del Torner	Borda del Torner		42.58333	1.48333	S	FRM	AD		00				0		1809	Europe/Andorra	1993-12-23
+3038933	Planell de la Tora	Planell de la Tora		42.55	1.6	T	UPLD	AD		00				0		2210	Europe/Andorra	1993-12-23
+3038934	Clots de la Tora	Clots de la Tora		42.46667	1.58333	H	RVN	AD		00				0		2367	Europe/Andorra	1993-12-23
+3038935	Prat del Toni	Prat del Toni		42.55	1.61667	L	GRAZ	AD		00				0		2206	Europe/Andorra	1993-12-23
+3038936	Molí del Tomàs	Moli del Tomas		42.58333	1.65	S	ML	AD		00				0		1767	Europe/Andorra	1993-12-23
+3038937	Cortals de Tolse	Cortals de Tolse		42.45	1.48333	S	CRRL	AD		00				0		1111	Europe/Andorra	1993-12-23
+3038938	Bosc de Tolse	Bosc de Tolse		42.45	1.48333	V	FRST	AD		00				0		1111	Europe/Andorra	1993-12-23
+3038939	Tolse	Tolse		42.45	1.48333	S	HUTS	AD		00				0		1111	Europe/Andorra	1993-12-23
+3038940	Basera dels Tolls de l’Olla	Basera dels Tolls de l'Olla		42.48333	1.45	T	CLF	AD		00				0		1195	Europe/Andorra	1993-12-23
+3038941	Tolls de l’Olla	Tolls de l'Olla		42.46667	1.56667	L	LCTY	AD		00				0		2365	Europe/Andorra	1993-12-23
+3038942	Torrent del Tirader	Torrent del Tirader		42.53333	1.6	H	STM	AD		00				0		1888	Europe/Andorra	1993-12-23
+3038943	Canal del Timbarro	Canal del Timbarro		42.5	1.46667	H	STM	AD		00				0		1678	Europe/Andorra	1993-12-23
+3038944	Terres de Serra	Terres de Serra		42.48333	1.5	L	LCTY	AD		00				0		1631	Europe/Andorra	1993-12-23
+3038945	Terres de Sant Miguel	Terres de Sant Miguel		42.5	1.58333	L	LCTY	AD		00				0		1888	Europe/Andorra	1993-12-23
+3038946	Terres del Torrent Pregó	Terres del Torrent Prego		42.55	1.58333	L	LCTY	AD		00				0		1499	Europe/Andorra	1993-12-23
+3038947	Terres del Solà	Terres del Sola		42.55	1.55	L	LCTY	AD		00				0		2097	Europe/Andorra	1993-12-23
+3038948	Terres de Jacques	Terres de Jacques		42.56667	1.61667	L	LCTY	AD		00				0		1920	Europe/Andorra	1993-12-23
+3038949	Obaga de les Terres de Casamanya	Obaga de les Terres de Casamanya		42.56667	1.55	T	SLP	AD		00				0		1996	Europe/Andorra	1993-12-23
+3038950	Canal del Terrer Roig	Canal del Terrer Roig		42.58333	1.46667	H	STM	AD		00				0		1643	Europe/Andorra	1993-12-23
+3038951	Terrer Roig	Terrer Roig		42.58333	1.45	L	LCTY	AD		00				0		2156	Europe/Andorra	1993-12-23
+3038952	Clots dels Terregalls	Clots dels Terregalls		42.61667	1.61667	H	STMH	AD		00				0		2352	Europe/Andorra	1993-12-23
+3038953	Terregalls	Terregalls		42.5	1.51667	L	LCTY	AD		00				0		1410	Europe/Andorra	1993-12-23
+3038954	Terra del Pou	Terra del Pou		42.46667	1.48333	L	LCTY	AD		00				0		1134	Europe/Andorra	1993-12-23
+3038955	Terra Bogada	Terra Bogada		42.46667	1.5	L	LCTY	AD		00				0		1383	Europe/Andorra	1993-12-23
+3038956	Canal del Teixó	Canal del Teixo		42.55	1.5	H	STM	AD		00				0		1292	Europe/Andorra	1993-12-23
+3038957	Coma de Teix	Coma de Teix		42.46667	1.46667	T	SLP	AD		00				0		1340	Europe/Andorra	1993-12-23
+3038958	Font de les Taules	Font de les Taules		42.55	1.55	H	SPNG	AD		00				0		2097	Europe/Andorra	1993-12-23
+3038959	Coma Tarterosa	Coma Tarterosa		42.48333	1.45	H	RVN	AD		00				0		1195	Europe/Andorra	1993-12-23
+3038960	Bosc de la Tarterosa	Bosc de la Tarterosa		42.6	1.65	V	FRST	AD		00				0		2131	Europe/Andorra	1993-12-23
+3038961	Tarter Gran	Tarter Gran		42.58333	1.45	L	LCTY	AD		00				0		2156	Europe/Andorra	1993-12-23
+3038962	Tartera Gran	Tartera Gran		42.48333	1.46667	L	LCTY	AD		00				0		1148	Europe/Andorra	1993-12-23
+3038963	Pont del Tarter	Pont del Tarter		42.58333	1.65	S	BDG	AD		00				0		1767	Europe/Andorra	1993-12-23
+3038964	Coll de la Tàpia	Coll de la Tapia		42.46667	1.48333	T	PASS	AD		00				0		1134	Europe/Andorra	1993-12-23
+3038965	Canal Tancada	Canal Tancada		42.48333	1.55	H	STM	AD		00				0		2233	Europe/Andorra	1993-12-23
+3038966	Roc del Tampuent	Roc del Tampuent		42.58333	1.48333	T	RK	AD		00				0		1809	Europe/Andorra	1993-12-23
+3038967	Basers de les Tallades	Basers de les Tallades		42.5	1.46667	T	CLF	AD		00				0		1678	Europe/Andorra	1993-12-23
+3038968	Bosc de la Tallada Nova	Bosc de la Tallada Nova		42.58333	1.48333	V	FRST	AD		00				0		1809	Europe/Andorra	1993-12-23
+3038969	Camí de la Tallada	Cami de la Tallada		42.48333	1.56667	R	TRL	AD		00				0		2231	Europe/Andorra	1993-12-23
+3038970	Canal del Tabanell	Canal del Tabanell		42.56667	1.51667	H	STM	AD		00				0		1500	Europe/Andorra	1993-12-23
+3038971	Bosc del Tabanell	Bosc del Tabanell		42.58333	1.5	V	FRST	AD		00				0		1595	Europe/Andorra	1993-12-23
+3038972	Suriguera	Suriguera		42.58333	1.61667	T	SLP	AD		00				0		1707	Europe/Andorra	1993-12-23
+3038973	Sudornar	Sudornar		42.58333	1.45	T	SLP	AD		00				0		2156	Europe/Andorra	1993-12-23
+3038974	Font del Sucre	Font del Sucre		42.51667	1.46667	H	SPNG	AD		00				0		1840	Europe/Andorra	1993-12-23
+3038975	Costa de la Sucarana	Costa de la Sucarana		42.6	1.5	T	SLP	AD		00				0		1923	Europe/Andorra	1993-12-23
+3038976	Canya de la Sucarana	Canya de la Sucarana		42.6	1.5	T	GRGE	AD		00				0		1923	Europe/Andorra	1993-12-23
+3038977	Borda del Sucarana	Borda del Sucarana		42.55	1.58333	S	HUTS	AD		00				0		1499	Europe/Andorra	1993-12-23
+3038978	Riu de Sorteny	Riu de Sorteny		42.62341	1.54869	H	STM	AD		00				0		1950	Europe/Andorra	2011-04-19
+3038979	Pla de Sorteny	Pla de Sorteny		42.61952	1.58872	T	UPLD	AD		00				0		2524	Europe/Andorra	2011-04-19
+3038980	Marrades de Sorteny	Marrades de Sorteny		42.61667	1.55	R	TRL	AD		00				0		2007	Europe/Andorra	1993-12-23
+3038981	Sorteny	Sorteny		42.61667	1.58333	A	ADMD	AD		00				0		2374	Europe/Andorra	1993-12-23
+3038982	Riu de les Soronelles	Riu de les Soronelles		42.53333	1.65	H	STM	AD		00				0		2508	Europe/Andorra	1993-12-23
+3038983	Collada de les Soronelles	Collada de les Soronelles		42.53333	1.65	T	PASS	AD		00				0		2508	Europe/Andorra	1993-12-23
+3038984	Pic de les Sorobilles	Pic de les Sorobilles		42.56667	1.53333	T	PK	AD		00				0		1669	Europe/Andorra	1993-12-23
+3038985	Riu de Sornàs	Riu de Sornas		42.56667	1.53333	H	STM	AD		00				0		1669	Europe/Andorra	1993-12-23
+3038986	Clot de Sornàs	Clot de Sornas		42.56667	1.55	H	RVN	AD		00				0		1996	Europe/Andorra	1993-12-23
+3038987	Sornàs	Sornas	Sornas,Sornàs	42.5654	1.5287	P	PPL	AD		05				0		1514	Europe/Andorra	2011-11-05
+3038988	Riu de Soriguera	Riu de Soriguera	Riu de Soriguera,Riu de Suriguera	42.58333	1.61667	H	STM	AD	AD	00				0		1707	Europe/Andorra	2011-11-05
+3038989	Solana del Soriguer	Solana del Soriguer		42.56667	1.55	T	SLP	AD		00				0		1996	Europe/Andorra	1993-12-23
+3038990	Clot Sord	Clot Sord		42.6	1.65	T	CRQ	AD		00				0		2131	Europe/Andorra	1993-12-23
+3038991	Solà de Soquer	Sola de Soquer		42.45	1.48333	T	SLP	AD		00				0		1111	Europe/Andorra	1993-12-23
+3038992	Riu de Soplanàs	Riu de Soplanas	Riu de Soplanars,Riu de Soplanas,Riu de Soplanàs	42.58333	1.63333	H	STM	AD	AD	00				0		1722	Europe/Andorra	2011-11-05
+3038993	Borda de Som	Borda de Som		42.56667	1.58333	S	HUTS	AD		00				0		1919	Europe/Andorra	1993-12-23
+3038994	Roc de Solobre	Roc de Solobre		42.48333	1.51667	T	RKS	AD		00				0		2061	Europe/Andorra	1993-12-23
+3038995	Bosc de Solobre	Bosc de Solobre		42.48333	1.5	V	FRST	AD		00				0		1631	Europe/Andorra	1993-12-23
+3038996	Bosc del Soleador	Bosc del Soleador		42.6	1.51667	V	FRST	AD		00				0		1445	Europe/Andorra	1993-12-23
+3038997	Camí de Soldeu	Cami de Soldeu		42.58333	1.66667	R	TRL	AD		00				0		2159	Europe/Andorra	1993-12-23
+3038998	Bosc de Soldeu	Bosc de Soldeu	Bois de Soldeu,Bosc de Soldeu,Bosque de Soldeu	42.57107	1.65402	V	FRST	AD		00				0		1988	Europe/Andorra	2011-11-05
+3038999	Soldeu	Soldeu		42.57688	1.66769	P	PPL	AD		02				0		2159	Europe/Andorra	2007-04-16
+3039000	Solana del Solanyó	Solana del Solanyo		42.53333	1.55	T	SLP	AD		00				0		1344	Europe/Andorra	1993-12-23
+3039001	Riu del Solanyò	Riu del Solanyo		42.53333	1.55	H	STM	AD		00				0		1344	Europe/Andorra	1993-12-23
+3039002	Bosc del Solanyó	Bosc del Solanyo		42.55	1.45	V	FRST	AD		00				0		1788	Europe/Andorra	1993-12-23
+3039003	Barranc del Solanyó	Barranc del Solanyo		42.55	1.45	H	STM	AD		00				0		1788	Europe/Andorra	1993-12-23
+3039004	Solans	Solans		42.53333	1.6	L	LCTY	AD		00				0		1888	Europe/Andorra	1993-12-23
+3039005	Solanet de Ràmio	Solanet de Ramio		42.5	1.56667	L	LCTY	AD		00				0		1776	Europe/Andorra	1993-12-23
+3039006	Terregalls del Solanet	Terregalls del Solanet		42.63333	1.6	T	RDGE	AD		00				0		2635	Europe/Andorra	1993-12-23
+3039007	Bosc del Solanet	Bosc del Solanet		42.55	1.48333	V	FRST	AD		00				0		1548	Europe/Andorra	1993-12-23
+3039008	Solanes de la Peguera	Solanes de la Peguera		42.45	1.51667	A	ADMD	AD		00				0		1790	Europe/Andorra	1993-12-23
+3039009	Serra de les Solanelles	Serra de les Solanelles		42.55	1.66667	T	RDGE	AD		00				0		2224	Europe/Andorra	1993-12-23
+3039010	Riu de les Solanelles	Riu de les Solanelles		42.55	1.68333	H	STM	AD		00				0		2254	Europe/Andorra	1993-12-23
+3039011	Collet de les Solanelles	Collet de les Solanelles		42.55	1.61667	T	PASS	AD		00				0		2206	Europe/Andorra	1993-12-23
+3039012	Collada de les Solanelles	Collada de les Solanelles		42.55	1.66667	T	PASS	AD		00				0		2224	Europe/Andorra	1993-12-23
+3039013	Clot de les Solanelles	Clot de les Solanelles		42.55	1.63333	H	RVN	AD		00				0		2336	Europe/Andorra	1993-12-23
+3039014	Canal de les Solanelles	Canal de les Solanelles		42.55	1.63333	H	STM	AD		00				0		2336	Europe/Andorra	1993-12-23
+3039015	Cabana de les Solanelles	Cabana de les Solanelles		42.53333	1.66667	S	HUT	AD		00				0		2489	Europe/Andorra	1993-12-23
+3039016	Solanelles	Solanelles		42.55	1.66667	L	LCTY	AD		00				0		2224	Europe/Andorra	1993-12-23
+3039017	Barranc de la Solana del Pas de la Casa	Barranc de la Solana del Pas de la Casa		42.53333	1.73333	H	STM	AD		00				0		2300	Europe/Andorra	1993-12-23
+3039018	Solana del Lloser d’Ordino	Solana del Lloser d'Ordino		42.55	1.51667	L	LCTY	AD		00				0		1397	Europe/Andorra	1993-12-23
+3039019	Riu de la Solana del Forn	Riu de la Solana del Forn		42.56154	1.67948	H	STM	AD		00				0		2094	Europe/Andorra	2011-04-19
+3039020	Obagot de la Solana del Forn	Obagot de la Solana del Forn		42.55	1.66667	T	SLP	AD		00				0		2224	Europe/Andorra	1993-12-23
+3039021	Solana del Forn	Solana del Forn		42.55	1.66667	A	ADMD	AD		00				0		2224	Europe/Andorra	1993-12-23
+3039022	Solana de l’Estall Serrer	Solana de l'Estall Serrer		42.5	1.61667	A	ADMD	AD		00				0		2560	Europe/Andorra	1993-12-23
+3039023	Solana de les Aubes	Solana de les Aubes		42.56667	1.56667	L	LCTY	AD		00				0		2089	Europe/Andorra	1993-12-23
+3039024	Solana de la Baronia	Solana de la Baronia		42.53333	1.61667	A	ADMD	AD		00				0		2237	Europe/Andorra	1993-12-23
+3039025	Prats de la Solana	Prats de la Solana		42.56667	1.78333	L	GRAZ	AD		00				0		1680	Europe/Andorra	1993-12-23
+3039026	Camí de la Solana	Cami de la Solana		42.43333	1.45	R	TRL	AD		00				0		877	Europe/Andorra	1993-12-23
+3039027	Bosc de la Solana	Bosc de la Solana		42.51667	1.46667	V	FRST	AD		00				0		1840	Europe/Andorra	1993-12-23
+3039028	Solà de Soldeu	Sola de Soldeu		42.58333	1.66667	A	ADMD	AD		00				0		2159	Europe/Andorra	1993-12-23
+3039029	Serra del Solà de Sispony	Serra del Sola de Sispony		42.53333	1.48333	T	MT	AD		00				0		1677	Europe/Andorra	1993-12-23
+3039030	Pic del Solà d’Erts	Pic del Sola d'Erts		42.56667	1.5	T	PK	AD		00				0		1636	Europe/Andorra	1993-12-23
+3039031	Solà d’Erts	Sola d'Erts		42.56667	1.5	A	ADMD	AD		00				0		1636	Europe/Andorra	1993-12-23
+3039032	Solà de Riambert	Sola de Riambert		42.58333	1.53333	A	ADMD	AD		00				0		1924	Europe/Andorra	1993-12-23
+3039033	Serra del Solà de Ràmio	Serra del Sola de Ramio		42.5	1.58333	T	MT	AD		00				0		1888	Europe/Andorra	1993-12-23
+3039034	Solà de Ràmio	Sola de Ramio		42.5	1.58333	A	ADMD	AD		00				0		1888	Europe/Andorra	1993-12-23
+3039035	Bosc del Solà d’Envalira	Bosc del Sola d'Envalira		42.55	1.68333	V	FRST	AD		00				0		2254	Europe/Andorra	1993-12-23
+3039036	Carena del Solà d’Engordany	Carena del Sola d'Engordany		42.51667	1.55	T	RDGE	AD		00				0		1322	Europe/Andorra	1993-12-23
+3039037	Solá d’Engordany	Sola d'Engordany		42.51667	1.53333	A	ADMD	AD		00				0		1460	Europe/Andorra	1993-12-23
+3039038	Solà d’Enclar	Sola d'Enclar		42.51667	1.48333	A	ADMD	AD		00				0		1839	Europe/Andorra	1993-12-23
+3039039	Solà d’Encamp	Sola d'Encamp		42.53333	1.58333	A	ADMD	AD		00				0		1571	Europe/Andorra	1993-12-23
+3039040	Cresta del Solà de Nadal	Cresta del Sola de Nadal		42.51667	1.51667	T	SPUR	AD		00				0		1265	Europe/Andorra	1993-12-23
+3039041	Aspres del Solà de Nadal	Aspres del Sola de Nadal		42.51667	1.51667	V	VINS	AD		00				0		1265	Europe/Andorra	1993-12-23
+3039042	Solà de Mossers	Sola de Mossers		42.45	1.46667	A	ADMD	AD		00				0		935	Europe/Andorra	1993-12-23
+3039043	Solà de Mereig	Sola de Mereig		42.56667	1.58333	L	LCTY	AD		00				0		1919	Europe/Andorra	1993-12-23
+3039044	Solà del Tarter	Sola del Tarter		42.58333	1.65	A	ADMD	AD		00				0		1767	Europe/Andorra	1993-12-23
+3039045	Solà dels Sulls	Sola dels Sulls		42.48333	1.56667	A	ADMD	AD		00				0		2231	Europe/Andorra	1993-12-23
+3039046	Solà dels Plans	Sola dels Plans		42.58333	1.63333	A	ADMD	AD		00				0		1722	Europe/Andorra	1993-12-23
+3039047	Serra del Sola del Quart Mitger	Serra del Sola del Quart Mitger		42.55	1.55	T	RDGE	AD		00				0		2097	Europe/Andorra	1993-12-23
+3039048	Solà del Quart Mitger	Sola del Quart Mitger		42.55	1.53333	A	ADMD	AD		00				0		1593	Europe/Andorra	1993-12-23
+3039049	Solà del Pui	Sola del Pui		42.55	1.51667	A	ADMD	AD		00				0		1397	Europe/Andorra	1993-12-23
+3039050	Cap del Solà de les Comes	Cap del Sola de les Comes		42.58333	1.5	T	PK	AD		00				0		1595	Europe/Andorra	1993-12-23
+3039051	Canal del Solà de les Comes	Canal del Sola de les Comes		42.56667	1.48333	H	STM	AD		00				0		1508	Europe/Andorra	1993-12-23
+3039052	Solà de la Moixella	Sola de la Moixella		42.45	1.48333	A	ADMD	AD		00				0		1111	Europe/Andorra	1993-12-23
+3039053	Balmes del Solà de l’Allau	Balmes del Sola de l'Allau		42.6	1.53333	T	CLF	AD		00				0		1695	Europe/Andorra	1993-12-23
+3039054	Solà de l’Aldosa	Sola de l'Aldosa		42.58333	1.61667	A	ADMD	AD		00				0		1707	Europe/Andorra	1993-12-23
+3039055	Solà de la Farga	Sola de la Farga		42.48333	1.6	A	ADMD	AD		00				0		2250	Europe/Andorra	1993-12-23
+3039056	Canals del Solà de Juclar	Canals del Sola de Juclar		42.6	1.7	H	RVN	AD		00				0		2354	Europe/Andorra	1993-12-23
+3039057	Solà d’Arcavell	Sola d'Arcavell	Sola d'Arcabell,Sola d'Arcavell,Sola d’Arcabell,Solà d’Arcavell	42.43333	1.48333	A	ADMD	AD		00				0		1228	Europe/Andorra	2011-11-05
+3039058	Solà d’Andorra	Sola d'Andorra		42.51667	1.5	A	ADMD	AD		00				0		1688	Europe/Andorra	1993-12-23
+3039059	Solà d’Aixovall	Sola d'Aixovall		42.48333	1.48333	A	ADMD	AD		00				0		981	Europe/Andorra	1993-12-23
+3039060	Riu del Solà	Riu del Sola		42.55	1.46667	H	STM	AD		00				0		1585	Europe/Andorra	1993-12-23
+3039061	Clot del Solà	Clot del Sola		42.46667	1.46667	H	RVN	AD		00				0		1340	Europe/Andorra	1993-12-23
+3039062	Carrera del Solà	Carrera del Sola		42.53333	1.58333	R	TRL	AD		00				0		1571	Europe/Andorra	1993-12-23
+3039063	Costa del Sodorn	Costa del Sodorn		42.5	1.46667	T	SLP	AD		00				0		1678	Europe/Andorra	1993-12-23
+3039064	Pla del Socarrat	Pla del Socarrat		42.55	1.6	T	UPLD	AD		00				0		2210	Europe/Andorra	1993-12-23
+3039065	Camí del Socarrat	Cami del Socarrat		42.58333	1.63333	R	TRL	AD		00				0		1722	Europe/Andorra	1993-12-23
+3039066	Bosc del Socarrat	Bosc del Socarrat		42.58333	1.65	V	FRST	AD		00				0		1767	Europe/Andorra	1993-12-23
+3039067	Vial de la Socarrada de Coll Carnisser	Vial de la Socarrada de Coll Carnisser		42.58333	1.46667	R	RD	AD		00				0		1643	Europe/Andorra	1993-12-23
+3039068	Pala de Sobre l’Estany	Pala de Sobre l'Estany		42.61667	1.71667	T	CLF	AD		00				0		2352	Europe/Andorra	1993-12-23
+3039069	Pala de Sobre les Basses	Pala de Sobre les Basses		42.58333	1.7	T	SLP	AD		00				0		2584	Europe/Andorra	1993-12-23
+3039070	Basers de Sobre la Pleta	Basers de Sobre la Pleta		42.6	1.46667	T	CLF	AD		00				0		2421	Europe/Andorra	1993-12-23
+3039071	Sobre dels Camps de la Cortinada	Sobre dels Camps de la Cortinada		42.58333	1.5	A	ADMD	AD		00				0		1595	Europe/Andorra	1993-12-23
+3039072	Planells Sobirans	Planells Sobirans		42.58333	1.46667	T	UPLD	AD		00				0		1643	Europe/Andorra	1993-12-23
+3039073	Riu del Sisqueró	Riu del Sisquero		42.6	1.7	H	STM	AD		00				0		2354	Europe/Andorra	1993-12-23
+3039074	Camí del Sisquero	Cami del Sisquero		42.6	1.68333	R	TRL	AD		00				0		2089	Europe/Andorra	1993-12-23
+3039075	Solà de Sispony	Sola de Sispony		42.53333	1.48333	T	SLP	AD		00				0		1677	Europe/Andorra	1993-12-23
+3039076	Camí de Sispony	Cami de Sispony		42.53333	1.46667	R	TRL	AD		00				0		1846	Europe/Andorra	1993-12-23
+3039077	Sispony	Sispony		42.53355	1.51481	P	PPL	AD		04				0		1252	Europe/Andorra	2011-04-19
+3039078	Pletes del Siscaró	Pletes del Siscaro		42.58333	1.7	L	GRAZ	AD		00				0		2584	Europe/Andorra	1993-12-23
+3039079	Estanys del Siscaro	Estanys del Siscaro		42.58333	1.7	H	LKS	AD		00				0		2584	Europe/Andorra	1993-12-23
+3039080	Canals del Siscaró	Canals del Siscaro		42.58333	1.7	H	RVN	AD		00				0		2584	Europe/Andorra	1993-12-23
+3039081	Pic de Siscarou	Pic de Siscarou	Pic de Siscarou,Pico de Siscarou,Siscaro,Siscaró	42.6	1.73333	T	PK	AD		00				0		2383	Europe/Andorra	2011-11-05
+3039082	Siscaró	Siscaro		42.58333	1.71667	A	ADMD	AD		00				0		2553	Europe/Andorra	1993-12-23
+3039083	Marrades del Siscar	Marrades del Siscar		42.58333	1.71667	R	TRL	AD		00				0		2553	Europe/Andorra	1993-12-23
+3039084	Canals del Siscar	Canals del Siscar		42.6	1.71667	H	RVN	AD		00				0		2516	Europe/Andorra	1993-12-23
+3039085	Basses del Siscar	Basses del Siscar		42.58333	1.71667	H	LKS	AD		00				0		2553	Europe/Andorra	1993-12-23
+3039086	Sincloset	Sincloset		42.48333	1.5	T	MT	AD		00				0		1631	Europe/Andorra	1993-12-23
+3039087	Port de Siguer	Port de Siguer	Port de Siguer	42.65	1.56667	T	PASS	AD		00				0		2471	Europe/Andorra	2011-11-05
+3039088	Bosc del Sigarró	Bosc del Sigarro		42.51667	1.6	V	FRST	AD		00				0		2085	Europe/Andorra	1993-12-23
+3039089	Canal de la Sicalma	Canal de la Sicalma		42.5	1.48333	H	STM	AD		00				0		1316	Europe/Andorra	1993-12-23
+3039090	Portella de Satut	Portella de Satut	Port de Setut,Portella de Satut,Portella de Setut	42.46667	1.63333	T	PK	AD		00				0		2619	Europe/Andorra	2011-11-05
+3039091	Cabana de Setut	Cabana de Setut		42.48333	1.63333	S	HUT	AD		00				0		2296	Europe/Andorra	1993-12-23
+3039092	Basses de Setut	Basses de Setut		42.48333	1.65	H	LKS	AD		00				0		2658	Europe/Andorra	1993-12-23
+3039093	Setut	Setut		42.46667	1.65	A	ADMD	AD		00				0		2700	Europe/Andorra	1993-12-23
+3039094	Carretera de Setúria	Carretera de Seturia		42.55	1.48333	R	RD	AD		00				0		1548	Europe/Andorra	1993-12-23
+3039095	Camí de Setúria	Cami de Seturia		42.55	1.46667	R	TRL	AD		00				0		1585	Europe/Andorra	1993-12-23
+3039096	Bordes de Setúria	Bordes de Seturia		42.53288	1.43718	S	HUTS	AD		00				0		1972	Europe/Andorra	2011-04-19
+3039097	Setúria	Seturia		42.55	1.43333	A	ADMD	AD		00				0		1949	Europe/Andorra	1993-12-23
+3039098	Tarteres de la Serrera	Tarteres de la Serrera		42.61667	1.58333	T	TAL	AD		00				0		2374	Europe/Andorra	1993-12-23
+3039099	Riu de la Serrera	Riu de la Serrera		42.61667	1.56667	H	STM	AD		00				0		2228	Europe/Andorra	1993-12-23
+3039100	Pleta de la Serrera	Pleta de la Serrera		42.61667	1.58333	L	GRAZ	AD		00				0		2374	Europe/Andorra	1993-12-23
+3039101	Pic de la Serrera	Pic de la Serrera	Pic de Serrere,Pic de Serrère,Pic de la Serrera,Serrera	42.63333	1.6	T	PK	AD		00				0		2635	Europe/Andorra	2011-11-05
+3039102	Pas de la Serrera	Pas de la Serrera		42.61667	1.58333	T	PASS	AD		00				0		2374	Europe/Andorra	1993-12-23
+3039103	Clots de la Serrera	Clots de la Serrera		42.61667	1.6	H	STMH	AD		00				0		2528	Europe/Andorra	1993-12-23
+3039104	Aspres de la Serrera	Aspres de la Serrera		42.61667	1.6	V	VINS	AD		00				0		2528	Europe/Andorra	1993-12-23
+3039105	Canal de Serrats	Canal de Serrats		42.53333	1.5	H	STM	AD		00				0		1357	Europe/Andorra	1993-12-23
+3039106	Camí del Serrat Pla	Cami del Serrat Pla		42.43333	1.46667	R	TRL	AD		00				0		1113	Europe/Andorra	1993-12-23
+3039107	Bosc del Serrat Llong	Bosc del Serrat Llong		42.51667	1.48333	V	FRST	AD		00				0		1839	Europe/Andorra	1993-12-23
+3039108	Planell del Serrat del Tronc	Planell del Serrat del Tronc		42.58333	1.61667	T	UPLD	AD		00				0		1707	Europe/Andorra	1993-12-23
+3039109	Cabana del Serrat de la Barracota	Cabana del Serrat de la Barracota		42.48333	1.63333	S	HUT	AD		00				0		2296	Europe/Andorra	1993-12-23
+3039110	Pic de Serra Seca	Pic de Serra Seca		42.51667	1.7	T	PK	AD		00				0		2435	Europe/Andorra	1993-12-23
+3039111	Canal de Serra Plana	Canal de Serra Plana		42.48333	1.48333	H	STM	AD		00				0		981	Europe/Andorra	1993-12-23
+3039112	Riu de Serrana	Riu de Serrana		42.55	1.51667	H	STM	AD		00				0		1397	Europe/Andorra	1993-12-23
+3039113	Pic de Serra Mitjana	Pic de Serra Mitjana		42.47479	1.61523	T	PK	AD		00				0		2418	Europe/Andorra	2011-04-19
+3039114	Estany de Serra Mitjana	Estany de Serra Mitjana		42.46667	1.6	H	LK	AD		00				0		2449	Europe/Andorra	1993-12-23
+3039115	Canal Ampla de Serra Mitjana	Canal Ampla de Serra Mitjana		42.46667	1.61667	H	STM	AD		00				0		2448	Europe/Andorra	1993-12-23
+3039116	Canal de la Serradora	Canal de la Serradora		42.48333	1.46667	H	STM	AD		00				0		1148	Europe/Andorra	1993-12-23
+3039117	Canal Serradora	Canal Serradora		42.5	1.56667	H	STM	AD		00				0		1776	Europe/Andorra	1993-12-23
+3039118	Cap de la Serra dels Isards	Cap de la Serra dels Isards		42.58333	1.58333	T	PK	AD		00				0		1993	Europe/Andorra	1993-12-23
+3039119	Serrat dels Serradells	Serrat dels Serradells		42.61667	1.53333	T	SPUR	AD		00				0		1609	Europe/Andorra	1993-12-23
+3039120	Cortal de la Serra	Cortal de la Serra		42.53333	1.5	S	CRRL	AD		00				0		1357	Europe/Andorra	1993-12-23
+3039121	Cap de la Serra	Cap de la Serra		42.61667	1.6	T	RDGE	AD		00				0		2528	Europe/Andorra	1993-12-23
+3039122	Roc de la Senyoreta	Roc de la Senyoreta		42.45	1.48333	T	RK	AD		00				0		1111	Europe/Andorra	1993-12-23
+3039123	Bosc de la Senyoreta	Bosc de la Senyoreta		42.45	1.48333	V	FRST	AD		00				0		1111	Europe/Andorra	1993-12-23
+3039124	Senyal Negre	Senyal Negre		42.65	1.55	T	MT	AD		00				0		2181	Europe/Andorra	1993-12-23
+3039125	Senyal de Missa	Senyal de Missa		42.46667	1.48333	T	PK	AD		00				0		1134	Europe/Andorra	1993-12-23
+3039126	Roc de Senders	Roc de Senders		42.5	1.53333	T	RK	AD		00				0		1574	Europe/Andorra	1993-12-23
+3039127	Sella	Sella		42.56667	1.6	T	CLF	AD		00				0		1655	Europe/Andorra	1993-12-23
+3039128	Riu del Seig	Riu del Seig		42.56667	1.61667	H	STM	AD		00				0		1920	Europe/Andorra	1993-12-23
+3039129	Canal del Seig	Canal del Seig		42.61667	1.53333	H	STM	AD		00				0		1609	Europe/Andorra	1993-12-23
+3039130	Solà de Segudet	Sola de Segudet		42.56667	1.53333	T	SLP	AD		00				0		1669	Europe/Andorra	1993-12-23
+3039131	Riu de Segudet	Riu de Segudet		42.5583	1.54304	H	STM	AD		00				0		1722	Europe/Andorra	2011-04-19
+3039132	Segudet	Segudet	Segudet	42.55755	1.53858	P	PPL	AD		05				0		1556	Europe/Andorra	2011-11-05
+3039133	Estany Segon	Estany Segon		42.61667	1.73333	H	LK	AD		00				0		2508	Europe/Andorra	1993-12-23
+3039134	Torrent del Segalars	Torrent del Segalars		42.55	1.58333	H	STM	AD		00				0		1499	Europe/Andorra	1993-12-23
+3039135	Camí de Sedornet	Cami de Sedornet		42.58333	1.51667	R	TRL	AD		00				0		1722	Europe/Andorra	1993-12-23
+3039136	Bordes de Sedornet	Bordes de Sedornet		42.58333	1.51667	S	HUTS	AD		00				0		1722	Europe/Andorra	1993-12-23
+3039137	Costa Seda	Costa Seda		42.48333	1.5	T	SLP	AD		00				0		1631	Europe/Andorra	1993-12-23
+3039138	Planells Secants	Planells Secants		42.43333	1.53333	T	UPLD	AD		00				0		2108	Europe/Andorra	1993-12-23
+3039139	Riu Sec	Riu Sec		42.51667	1.46667	H	STM	AD		00				0		1840	Europe/Andorra	1993-12-23
+3039140	Estany Sec	Estany Sec		42.46667	1.61667	H	LK	AD		00				0		2448	Europe/Andorra	1993-12-23
+3039141	Borda del Savoiano	Borda del Savoiano		42.56667	1.51667	S	HUTS	AD		00				0		1500	Europe/Andorra	1993-12-23
+3039142	Serra de la Sauvata	Serra de la Sauvata		42.56667	1.58333	T	RDGE	AD		00				0		1919	Europe/Andorra	1993-12-23
+3039143	Costa de la Sauvata	Costa de la Sauvata		42.56667	1.58333	T	SLP	AD		00				0		1919	Europe/Andorra	1993-12-23
+3039144	Roc del Sastre	Roc del Sastre	Roc del Sastra,Roc del Sastre	42.58333	1.61667	T	SPUR	AD	AD	00				0		1707	Europe/Andorra	2011-11-05
+3039145	Pont Sassanat	Pont Sassanat		42.5	1.55	S	BDG	AD		00				0		1566	Europe/Andorra	1993-12-23
+3039146	Saquet	Saquet		42.55	1.6	L	LCTY	AD		00				0		2210	Europe/Andorra	1993-12-23
+3039147	Roc de Sant Vicenç	Roc de Sant Vicenc		42.5	1.5	T	RK	AD		00				0		1135	Europe/Andorra	1993-12-23
+3039148	Collet de Sant Vicenç	Collet de Sant Vicenc		42.5	1.48333	T	PASS	AD		00				0		1316	Europe/Andorra	1993-12-23
+3039149	Solà de Santserra	Sola de Santserra		42.48333	1.46667	T	SLP	AD		00				0		1148	Europe/Andorra	1993-12-23
+3039150	Sant Romà de Vila	Sant Roma de Vila		42.53333	1.56667	S	CH	AD		00				0		1418	Europe/Andorra	1993-12-23
+3039151	Sant Romà de les Bons	Sant Roma de les Bons		42.53333	1.58333	S	CH	AD		00				0		1571	Europe/Andorra	1993-12-23
+3039152	Bosc de Sant Romà	Bosc de Sant Roma		42.45	1.5	V	FRST	AD		00				0		1614	Europe/Andorra	1993-12-23
+3039153	Sant Romà	Sant Roma		42.45	1.5	S	CH	AD		00				0		1614	Europe/Andorra	1993-12-23
+3039154	Sant Pere	Sant Pere	Sant Pere	42.57952	1.65362	P	PPL	AD		02				0		1767	Europe/Andorra	2011-11-05
+3039155	Sant Miquel d'Engolasters	Sant Miquel d'Engolasters	Sant Miquel d'Engolasters	42.51094	1.56008	S	CH	AD	AD	07				0		1661	Europe/Andorra	2007-04-05
+3039156	Sant Miquel de Fontaneda	Sant Miquel de Fontaneda	Sant Miquel,Sant Miquel de Fontaneda	42.45	1.46667	S	CH	AD	AD	00				0		935	Europe/Andorra	2011-11-05
+3039157	Solà de Sant Miquel	Sola de Sant Miquel		42.58333	1.66667	T	SLP	AD		00				0		2159	Europe/Andorra	1993-12-23
+3039158	Roc de Sant Miquel	Roc de Sant Miquel		42.58333	1.66667	T	CLF	AD		00				0		2159	Europe/Andorra	1993-12-23
+3039159	Drecera de Sant Martí	Drecera de Sant Marti		42.48333	1.5	R	TRL	AD		00				0		1631	Europe/Andorra	1993-12-23
+3039160	Sant Martí	Sant Marti		42.48333	1.5	T	UPLD	AD		00				0		1631	Europe/Andorra	1993-12-23
+3039161	Sant Martí	Sant Marti		42.48333	1.48333	S	RUIN	AD		00				0		981	Europe/Andorra	1993-12-23
+3039162	Parròquia de Sant Julià de Lòria	Parroquia de Sant Julia de Loria	Parroquia de Sant Julia de Loria,Parroquia de Sant Julià de Lòria,Sant Julia,Sant Julia de Loria,Sant Julià,Sant Julià de Lòria	42.46247	1.48247	A	ADM1	AD		06				9448		966	Europe/Andorra	2010-08-13
+3039163	Sant Julià de Lòria	Sant Julia de Loria	San Julia,San Julià,San-Dzhulija-de-Lorija,San-Khulija-de-Lorija,Sant Julia de Loria,Sant Julià de Lòria,sheng hu li ya-de luo li ya,Сан-ДжулиÑ-де-ЛориÑ,Сан-ХулиÑ-де-ЛориÑ,サン・ジュリア・デ・ロリア教区,圣胡利娅-德洛里亚,圣胡利娅ï¼å¾·æ´›é‡Œäºš	42.46372	1.49129	P	PPLA	AD		06				8022		1045	Europe/Andorra	2008-10-15
+3039164	Riu de Sant Josep	Riu de Sant Josep		42.56419	1.75244	H	STM	AD		00				0		1836	Europe/Andorra	2011-04-19
+3039165	Clot de Sant Josep	Clot de Sant Josep		42.56667	1.7	T	CRQ	AD		00				0		2375	Europe/Andorra	1993-12-23
+3039166	Sant Joan de Caselles	Sant Joan de Caselles	San Joan de Casettas,Sant Joan de Casellas,Sant Joan de Caselles	42.56988	1.60922	P	PPL	AD		02				0		1724	Europe/Andorra	2011-11-05
+3039167	Serrat de Sant Jaume	Serrat de Sant Jaume		42.53333	1.6	T	RDGE	AD		00				0		1888	Europe/Andorra	1993-12-23
+3039168	Sant Jaume	Sant Jaume		42.58333	1.63333	S	CH	AD		00				0		1722	Europe/Andorra	1993-12-23
+3039169	Sant Jaume	Sant Jaume	Sant Jaume,Sant Joums	42.53333	1.6	S	CH	AD	AD	00				0		1888	Europe/Andorra	2011-11-05
+3039170	Sant Esteve	Sant Esteve		42.43333	1.48333	S	CH	AD		00				0		1228	Europe/Andorra	1993-12-23
+3039171	Sant Esteve	Sant Esteve		42.43333	1.45	S	CH	AD		00				0		877	Europe/Andorra	1993-12-23
+3039172	Sant Cristòfol	Sant Cristofol		42.45	1.5	S	SHRN	AD		00				0		1614	Europe/Andorra	1993-12-23
+3039173	Sant Cristòfol	Sant Cristofol		42.53333	1.53333	S	CH	AD		00				0		1521	Europe/Andorra	1993-12-23
+3039174	Solà de Sant Cerni	Sola de Sant Cerni		42.46667	1.5	T	SLP	AD		00				0		1383	Europe/Andorra	1993-12-23
+3039175	Eglèsia de Sant Cerni	Eglesia de Sant Cerni		42.56667	1.6	S	CH	AD		00				0		1655	Europe/Andorra	1993-12-23
+3039176	Sant Cerni	Sant Cerni		42.46981	1.50133	S	CH	AD		00				0		1383	Europe/Andorra	2011-04-19
+3039177	Sant Antoni de la Grella	Sant Antoni de la Grella		42.53333	1.53333	S	CH	AD		00				0		1521	Europe/Andorra	1993-12-23
+3039178	Túnels de Sant Antoni	Tunels de Sant Antoni		42.51667	1.51667	R	TNLS	AD		00				0		1265	Europe/Andorra	1993-12-23
+3039179	Pont de Sant Antoni	Pont de Sant Antoni		42.51667	1.51667	S	BDG	AD		00				0		1265	Europe/Andorra	1993-12-23
+3039180	Pont de Santa Creu	Pont de Santa Creu		42.56667	1.6	S	BDG	AD		00				0		1655	Europe/Andorra	1993-12-23
+3039181	Santa Coloma	Santa Coloma	Santa Coloma	42.5	1.5	P	PPL	AD		07				0		1135	Europe/Andorra	2011-11-05
+3039182	Santa Caterina	Santa Caterina		42.55	1.51667	L	LCTY	AD		00				0		1397	Europe/Andorra	1993-12-23
+3039183	Cortal del Sansa	Cortal del Sansa		42.5	1.51667	S	CRRL	AD		00				0		1410	Europe/Andorra	1993-12-23
+3039184	Portella de Sanfons	Portella de Sanfons	Portella de Sanfons	42.56667	1.43333	T	PASS	AD		00				0		2402	Europe/Andorra	2011-11-05
+3039185	Pic de Sanfons	Pic de Sanfons	Pic de Sanfons	42.58333	1.43333	T	PK	AD		00				0		2412	Europe/Andorra	2011-11-05
+3039186	Roc de la Salve	Roc de la Salve		42.53333	1.6	T	RK	AD		00				0		1888	Europe/Andorra	1993-12-23
+3039187	Bosc de la Salvata	Bosc de la Salvata		42.45	1.51667	V	FRST	AD		00				0		1790	Europe/Andorra	1993-12-23
+3039188	Solana del Saltader	Solana del Saltader		42.56667	1.53333	T	SLP	AD		00				0		1669	Europe/Andorra	1993-12-23
+3039189	Clot del Saltader	Clot del Saltader		42.56667	1.46667	H	RVN	AD		00				0		1673	Europe/Andorra	1993-12-23
+3039190	Roc del Salt	Roc del Salt		42.58333	1.58333	T	RK	AD		00				0		1993	Europe/Andorra	1993-12-23
+3039191	Clot del Salt	Clot del Salt		42.58333	1.6	H	RVN	AD		00				0		1828	Europe/Andorra	1993-12-23
+3039192	Rius de les Salses	Rius de les Salses		42.63333	1.5	H	STM	AD		00				0		1979	Europe/Andorra	1993-12-23
+3039193	Pont de les Salines	Pont de les Salines		42.61667	1.53333	S	BDG	AD		00				0		1609	Europe/Andorra	1993-12-23
+3039194	Costa de les Salines	Costa de les Salines		42.61667	1.53333	T	SLP	AD		00				0		1609	Europe/Andorra	1993-12-23
+3039195	Bosc de les Salines	Bosc de les Salines		42.61667	1.53333	V	FRST	AD		00				0		1609	Europe/Andorra	1993-12-23
+3039196	Basses de les Salamandres	Basses de les Salamandres		42.6	1.66667	H	LKS	AD		00				0		1858	Europe/Andorra	1993-12-23
+3039197	Costa de la Salamandra	Costa de la Salamandra		42.55	1.43333	T	SLP	AD		00				0		1949	Europe/Andorra	1993-12-23
+3039198	Costa Salamandra	Costa Salamandra		42.5	1.48333	T	SLP	AD		00				0		1316	Europe/Andorra	1993-12-23
+3039199	Roca de la Sabina	Roca de la Sabina		42.56667	1.46667	T	SLP	AD		00				0		1673	Europe/Andorra	1993-12-23
+3039200	Cortal del Sabater	Cortal del Sabater		42.45	1.48333	S	CRRL	AD		00				0		1111	Europe/Andorra	1993-12-23
+3039201	Bosc del Sabater	Bosc del Sabater		42.45	1.48333	V	FRST	AD		00				0		1111	Europe/Andorra	1993-12-23
+3039202	Borda del Sabater	Borda del Sabater		42.45	1.48333	S	FRM	AD		00				0		1111	Europe/Andorra	1993-12-23
+3039203	Canal dels Rulls	Canal dels Rulls		42.48333	1.46667	H	STM	AD		00				0		1148	Europe/Andorra	1993-12-23
+3039204	Canal de Ruixol	Canal de Ruixol		42.58333	1.51667	H	STM	AD		00				0		1722	Europe/Andorra	1993-12-23
+3039205	Torrent del Ruïder	Torrent del Ruider		42.58333	1.48333	H	STM	AD		00				0		1809	Europe/Andorra	1993-12-23
+3039206	Roc del Ruïder	Roc del Ruider		42.58333	1.48333	T	SPUR	AD		00				0		1809	Europe/Andorra	1993-12-23
+3039207	Pala del Ruf	Pala del Ruf		42.58333	1.45	T	SLP	AD		00				0		2156	Europe/Andorra	1993-12-23
+3039208	Basses del Ruf	Basses del Ruf		42.58333	1.45	H	LKS	AD		00				0		2156	Europe/Andorra	1993-12-23
+3039209	Serrat de Rudielles	Serrat de Rudielles		42.5	1.45	T	MT	AD		00				0		1840	Europe/Andorra	1993-12-23
+3039210	Canal de Rudielles	Canal de Rudielles		42.5	1.45	H	STM	AD		00				0		1840	Europe/Andorra	1993-12-23
+3039211	Vial de Rubials	Vial de Rubials		42.48333	1.45	R	RD	AD		00				0		1195	Europe/Andorra	1993-12-23
+3039212	Torrent de Rubials	Torrent de Rubials		42.48333	1.45	H	STM	AD		00				0		1195	Europe/Andorra	1993-12-23
+3039213	Solana de Rubials	Solana de Rubials		42.48333	1.45	T	SLP	AD		00				0		1195	Europe/Andorra	1993-12-23
+3039214	Rua del Terrer Roi	Rua del Terrer Roi		42.43333	1.5	L	LCTY	AD		00				0		1804	Europe/Andorra	1993-12-23
+3039215	Bosc de Roures	Bosc de Roures		42.6	1.51667	V	FRST	AD		00				0		1445	Europe/Andorra	1993-12-23
+3039216	Collet de Roques Negres	Collet de Roques Negres		42.45	1.45	T	PASS	AD		00				0		1482	Europe/Andorra	1993-12-23
+3039217	Roques Negres	Roques Negres		42.45	1.45	L	LCTY	AD		00				0		1482	Europe/Andorra	1993-12-23
+3039218	Serrat de Roques Grosses	Serrat de Roques Grosses		42.58333	1.6	T	RDGE	AD		00				0		1828	Europe/Andorra	1993-12-23
+3039219	Canal de Roques Blanques	Canal de Roques Blanques		42.5	1.48333	H	STM	AD		00				0		1316	Europe/Andorra	1993-12-23
+3039220	Fontanal de les Roques	Fontanal de les Roques		42.53333	1.46667	H	SPNG	AD		00				0		1846	Europe/Andorra	1993-12-23
+3039221	Pleta de les Romes	Pleta de les Romes		42.65	1.55	L	GRAZ	AD		00				0		2181	Europe/Andorra	1993-12-23
+3039222	Font Roja	Font Roja		42.55	1.45	H	SPNG	AD		00				0		1788	Europe/Andorra	1993-12-23
+3039223	Font Roja	Font Roja		42.48333	1.5	H	SPNG	AD		00				0		1631	Europe/Andorra	1993-12-23
+3039224	Bassa Roja	Bassa Roja		42.6	1.66667	H	LK	AD		00				0		1858	Europe/Andorra	1993-12-23
+3039225	Grau Roig	Grau Roig		42.58333	1.46667	T	SLP	AD		00				0		1643	Europe/Andorra	1993-12-23
+3039226	Borda de Roig	Borda de Roig		42.56667	1.58333	S	HUT	AD		00				0		1919	Europe/Andorra	1993-12-23
+3039227	Fonts Roges	Fonts Roges		42.56667	1.46667	H	SPNG	AD		00				0		1673	Europe/Andorra	1993-12-23
+3039228	Fonts Roges	Fonts Roges		42.55	1.65	H	SPNG	AD		00				0		2432	Europe/Andorra	1993-12-23
+3039229	Canals Roges	Canals Roges		42.58333	1.71667	H	RVN	AD		00				0		2553	Europe/Andorra	1993-12-23
+3039230	Basses Roges	Basses Roges		42.46667	1.55	H	LKS	AD		00				0		2341	Europe/Andorra	1993-12-23
+3039231	Font Rodona	Font Rodona		42.55	1.41667	H	SPNG	AD		00				0		2105	Europe/Andorra	1993-12-23
+3039232	Costa Rodona	Costa Rodona		42.65	1.48333	T	SLP	AD		00				0		2341	Europe/Andorra	1993-12-23
+3039233	Costa Rodona	Costa Rodona		42.58333	1.45	T	SLP	AD		00				0		2156	Europe/Andorra	1993-12-23
+3039234	Costa Rodona	Costa Rodona		42.55	1.71667	T	SLP	AD		00				0		2192	Europe/Andorra	1993-12-23
+3039235	Boïga Rodona	Boiga Rodona		42.43333	1.53333	V	CULT	AD		00				0		2108	Europe/Andorra	1993-12-23
+3039236	Bosc del Ródol	Bosc del Rodol		42.48882	1.57683	V	FRST	AD		00				0		2246	Europe/Andorra	2011-04-19
+3039237	Turó Rodó	Turo Rodo		42.56667	1.55	T	PK	AD		00				0		1996	Europe/Andorra	1993-12-23
+3039238	Roc Rodó	Roc Rodo		42.56667	1.48333	T	SPUR	AD		00				0		1508	Europe/Andorra	1993-12-23
+3039239	Roc Rodó	Roc Rodo		42.56667	1.43333	T	SPUR	AD		00				0		2402	Europe/Andorra	1993-12-23
+3039240	Pla de Rodó	Pla de Rodo		42.55	1.43333	T	UPLD	AD		00				0		1949	Europe/Andorra	1993-12-23
+3039241	Estany Rodó	Estany Rodo		42.51667	1.68333	H	LK	AD		00				0		2352	Europe/Andorra	1993-12-23
+3039242	Estany Rodó	Estany Rodo		42.5	1.65	H	LK	AD		00				0		2542	Europe/Andorra	1993-12-23
+3039243	Bony Rodó	Bony Rodo		42.61667	1.55	T	SPUR	AD		00				0		2007	Europe/Andorra	1993-12-23
+3039244	Rocs Tous	Rocs Tous		42.55	1.58333	L	LCTY	AD		00				0		1499	Europe/Andorra	1993-12-23
+3039245	Rocs Negres	Rocs Negres		42.53333	1.61667	A	ADMD	AD		00				0		2237	Europe/Andorra	1993-12-23
+3039246	Planell del Roc Gros	Planell del Roc Gros		42.58333	1.48333	T	UPLD	AD		00				0		1809	Europe/Andorra	1993-12-23
+3039247	Bosc del Roc Gros	Bosc del Roc Gros		42.58333	1.48333	V	FRST	AD		00				0		1809	Europe/Andorra	1993-12-23
+3039248	Serra del Roc del Rellotge	Serra del Roc del Rellotge		42.61667	1.58333	T	MT	AD		00				0		2374	Europe/Andorra	1993-12-23
+3039249	Font del Roc del Porquer	Font del Roc del Porquer		42.6	1.45	H	SPNG	AD		00				0		2174	Europe/Andorra	1993-12-23
+3039250	Canal del Roc de la Grael	Canal del Roc de la Grael		42.51667	1.53333	H	STM	AD		00				0		1460	Europe/Andorra	1993-12-23
+3039251	Roca Podrida	Roca Podrida		42.55	1.51667	L	LCTY	AD		00				0		1397	Europe/Andorra	1993-12-23
+3039252	Costa de Roca Negra	Costa de Roca Negra		42.58333	1.58333	T	SLP	AD		00				0		1993	Europe/Andorra	1993-12-23
+3039253	Canal de Rocanegra	Canal de Rocanegra		42.5	1.46667	H	STM	AD		00				0		1678	Europe/Andorra	1993-12-23
+3039254	Canal de Roca Major	Canal de Roca Major		42.43333	1.5	H	RVN	AD		00				0		1804	Europe/Andorra	1993-12-23
+3039255	Planell de la Roca Grossa	Planell de la Roca Grossa		42.56667	1.7	T	UPLD	AD		00				0		2375	Europe/Andorra	1993-12-23
+3039256	Planell de Roca Grossa	Planell de Roca Grossa		42.55	1.66667	T	UPLD	AD		00				0		2224	Europe/Andorra	1993-12-23
+3039257	Canal de Rocafort	Canal de Rocafort		42.46667	1.48333	H	STM	AD		00				0		1134	Europe/Andorra	1993-12-23
+3039258	Rocafort	Rocafort		42.46667	1.48333	A	ADMD	AD		00				0		1134	Europe/Andorra	1993-12-23
+3039259	Solana de la Roca de la Sabina	Solana de la Roca de la Sabina		42.56667	1.46667	T	SLP	AD		00				0		1673	Europe/Andorra	1993-12-23
+3039260	Canal de la Roca Blanca	Canal de la Roca Blanca		42.51667	1.51667	H	STM	AD		00				0		1265	Europe/Andorra	1993-12-23
+3039261	Vial de la Roca	Vial de la Roca		42.55	1.6	R	RD	AD		00				0		2210	Europe/Andorra	1993-12-23
+3039262	Pala de la Roca	Pala de la Roca		42.55	1.61667	T	SLP	AD		00				0		2206	Europe/Andorra	1993-12-23
+3039263	Bosc de la Roca	Bosc de la Roca		42.55	1.46667	V	FRST	AD		00				0		1585	Europe/Andorra	1993-12-23
+3039264	Pont del Riu Montaner	Pont del Riu Montaner		42.53333	1.51667	S	BDG	AD		00				0		1361	Europe/Andorra	1993-12-23
+3039265	Camí del Riu del Seig	Cami del Riu del Seig		42.56667	1.6	R	TRL	AD		00				0		1655	Europe/Andorra	1993-12-23
+3039266	Riu del Seig	Riu del Seig		42.56667	1.61667	A	ADMD	AD		00				0		1920	Europe/Andorra	1993-12-23
+3039267	Forat del Riu dels Clots de Massat	Forat del Riu dels Clots de Massat		42.55	1.68333	H	RVN	AD		00				0		2254	Europe/Andorra	1993-12-23
+3039268	Fonts del Riu de les Cebes	Fonts del Riu de les Cebes		42.61667	1.58333	H	SPNG	AD		00				0		2374	Europe/Andorra	1993-12-23
+3039269	Costa del Riu de les Cebes	Costa del Riu de les Cebes		42.61667	1.58333	T	SLP	AD		00				0		2374	Europe/Andorra	1993-12-23
+3039270	Collada del Riu de les Cebes	Collada del Riu de les Cebes		42.61667	1.58333	T	SPUR	AD		00				0		2374	Europe/Andorra	1993-12-23
+3039271	Bony del Riu de les Cebes	Bony del Riu de les Cebes		42.61667	1.58333	T	RK	AD		00				0		2374	Europe/Andorra	1993-12-23
+3039272	Prats del Riu	Prats del Riu		42.46667	1.5	L	GRAZ	AD		00				0		1383	Europe/Andorra	1993-12-23
+3039273	Canal de Rita	Canal de Rita		42.53333	1.6	H	STM	AD		00				0		1888	Europe/Andorra	1993-12-23
+3039274	Solà del Riguer	Sola del Riguer		42.5	1.55	T	SLP	AD		00				0		1566	Europe/Andorra	1993-12-23
+3039275	Obaga del Riguer	Obaga del Riguer		42.48333	1.53333	T	SLP	AD		00				0		2255	Europe/Andorra	1993-12-23
+3039276	Bordes de Rigoder	Bordes de Rigoder		42.53333	1.61667	S	HUTS	AD		00				0		2237	Europe/Andorra	1993-12-23
+3039277	Bosc de les Ribes	Bosc de les Ribes		42.55	1.55	V	FRST	AD		00				0		2097	Europe/Andorra	1993-12-23
+3039278	Riberal d’Envalira	Riberal d'Envalira		42.53333	1.7	L	LCTY	AD		00				0		2357	Europe/Andorra	1993-12-23
+3039279	Canals de Ribera	Canals de Ribera		42.43333	1.48333	H	STM	AD		00				0		1228	Europe/Andorra	1993-12-23
+3039280	Ribassot	Ribassot		42.58333	1.48333	L	LCTY	AD		00				0		1809	Europe/Andorra	1993-12-23
+3039281	Torrent de Ribassols	Torrent de Ribassols		42.58333	1.48333	H	STM	AD		00				0		1809	Europe/Andorra	1993-12-23
+3039282	Torrent Ribal	Torrent Ribal		42.58333	1.48333	H	STM	AD		00				0		1809	Europe/Andorra	1993-12-23
+3039283	Tosa de Riba Escorjada	Tosa de Riba Escorjada		42.55	1.65	T	UPLD	AD		00				0		2432	Europe/Andorra	1993-12-23
+3039284	Solanelles de Riba Escorjada	Solanelles de Riba Escorjada		42.55	1.63333	T	SLP	AD		00				0		2336	Europe/Andorra	1993-12-23
+3039285	Planells de Riba Escorjada	Planells de Riba Escorjada		42.56667	1.63333	T	UPLD	AD		00				0		2016	Europe/Andorra	1993-12-23
+3039286	Camí de Riba Escorjada	Cami de Riba Escorjada		42.56667	1.63333	R	TRL	AD		00				0		2016	Europe/Andorra	1993-12-23
+3039287	Camí de Riba Escorjada	Cami de Riba Escorjada		42.55	1.6	R	TRL	AD		00				0		2210	Europe/Andorra	1993-12-23
+3039288	Riba Escorjada	Riba Escorjada		42.55	1.63333	A	ADMD	AD		00				0		2336	Europe/Andorra	1993-12-23
+3039289	Bosc de Riba	Bosc de Riba		42.55	1.58333	V	FRST	AD		00				0		1499	Europe/Andorra	1993-12-23
+3039290	Bosc del Riambert	Bosc del Riambert		42.56667	1.51667	V	FRST	AD		00				0		1500	Europe/Andorra	1993-12-23
+3039291	Riu de Rialb	Riu de Rialb	Riu de Rialb,Riu de Rialp	42.61667	1.53333	H	STM	AD	AD	00				0		1609	Europe/Andorra	2011-11-05
+3039292	Portella de Rialb	Portella de Rialb		42.63333	1.53333	T	PASS	AD		00				0		2072	Europe/Andorra	1993-12-23
+3039293	Basera de Rialb	Basera de Rialb		42.65	1.56667	T	CLF	AD		00				0		2471	Europe/Andorra	1993-12-23
+3039294	Rialb	Rialb		42.65	1.55	A	ADMD	AD		00				0		2181	Europe/Andorra	1993-12-23
+3039295	Pala de Rep	Pala de Rep		42.55	1.6	T	SLP	AD		00				0		2210	Europe/Andorra	1993-12-23
+3039296	Coll del Rep	Coll del Rep		42.45	1.46667	T	PASS	AD		00				0		935	Europe/Andorra	1993-12-23
+3039297	Cap de Rep	Cap de Rep	Cap de Rep,Cap de l' Ovella,Cap de l’ Ovella	42.54325	1.61092	T	PK	AD		00				0		2213	Europe/Andorra	2011-11-05
+3039298	Rep	Rep		42.53333	1.58333	A	ADMD	AD		00				0		1571	Europe/Andorra	1993-12-23
+3039299	Roc del Rellotge	Roc del Rellotge		42.61667	1.56667	T	SPUR	AD		00				0		2228	Europe/Andorra	1993-12-23
+3039300	Roc del Rellotge	Roc del Rellotge		42.56667	1.61667	T	RK	AD		00				0		1920	Europe/Andorra	1993-12-23
+3039301	Font de les Reïneres	Font de les Reineres		42.6	1.68333	H	SPNG	AD		00				0		2089	Europe/Andorra	1993-12-23
+3039302	Solana de la Regalíssia	Solana de la Regalissia		42.48333	1.41667	T	SLP	AD		00				0		1920	Europe/Andorra	1993-12-23
+3039303	Obaga de Redort	Obaga de Redort		42.55	1.56667	T	SLP	AD		00				0		1828	Europe/Andorra	1993-12-23
+3039304	Redort	Redort		42.56667	1.55	L	LCTY	AD		00				0		1996	Europe/Andorra	1993-12-23
+3039305	Clot de la Rectoria	Clot de la Rectoria		42.51667	1.5	H	RVN	AD		00				0		1688	Europe/Andorra	1993-12-23
+3039306	Serrat del Rec d’Areny	Serrat del Rec d'Areny		42.58333	1.46667	T	SPUR	AD		00				0		1643	Europe/Andorra	1993-12-23
+3039307	Bosc de Rèbols	Bosc de Rebols		42.46667	1.51667	V	FRST	AD		00				0		1985	Europe/Andorra	1993-12-23
+3039308	Pont de la Rebollissa	Pont de la Rebollissa		42.61667	1.53333	S	BDG	AD		00				0		1609	Europe/Andorra	1993-12-23
+3039309	Llanesques de les Rebes	Llanesques de les Rebes		42.63333	1.61667	T	CLF	AD		00				0		2541	Europe/Andorra	1993-12-23
+3039310	Clot de les Rebes	Clot de les Rebes		42.61667	1.61667	H	RVN	AD		00				0		2352	Europe/Andorra	1993-12-23
+3039311	Rebaixant del Maià	Rebaixant del Maia		42.56667	1.73333	L	LCTY	AD		00				0		2096	Europe/Andorra	1993-12-23
+3039312	Canal de la Rata	Canal de la Rata		42.58333	1.46667	H	RVN	AD		00				0		1643	Europe/Andorra	1993-12-23
+3039313	Port de Rat	Port de Rat	Port de Rat,Port de Rat du D'Auzat	42.62127	1.47371	T	PASS	AD	FR,AD	07				0		2442	Europe/Andorra	2007-03-04
+3039314	Bosc de Rasets	Bosc de Rasets		42.43333	1.53333	V	FRST	AD		00				0		2108	Europe/Andorra	1993-12-23
+3039315	Rasa de Perafita	Rasa de Perafita		42.48333	1.58333	T	UPLD	AD		00				0		2349	Europe/Andorra	1993-12-23
+3039316	Costa Rasa	Costa Rasa		42.46667	1.45	T	SLP	AD		00				0		1562	Europe/Andorra	1993-12-23
+3039317	Bosc de la Rasa	Bosc de la Rasa		42.46667	1.53333	V	FRST	AD		00				0		2332	Europe/Andorra	1993-12-23
+3039318	Presa de Ransol	Presa de Ransol		42.58333	1.63333	S	DAM	AD		00				0		1722	Europe/Andorra	1993-12-23
+3039319	Carretera de Ransol	Carretera de Ransol		42.58333	1.65	R	RD	AD		00				0		1767	Europe/Andorra	1993-12-23
+3039320	Ransol	Ransol		42.58137	1.63812	P	PPL	AD		02				0		1727	Europe/Andorra	2007-04-16
+3039321	Roca de Ràmio	Roca de Ramio		42.5	1.56667	T	RK	AD		00				0		1776	Europe/Andorra	1993-12-23
+3039322	Ràmio	Ramio		42.49702	1.57414	S	HUTS	AD		00				0		1776	Europe/Andorra	2011-04-19
+3039323	Canal del Ramer	Canal del Ramer		42.56667	1.48333	H	RVN	AD		00				0		1508	Europe/Andorra	1993-12-23
+3039324	Canal de la Ramenada	Canal de la Ramenada		42.5	1.51667	H	STM	AD		00				0		1410	Europe/Andorra	1993-12-23
+3039325	Camí Ral	Cami Ral		42.55	1.58333	R	TRL	AD		00				0		1499	Europe/Andorra	1993-12-23
+3039326	Camí Ral	Cami Ral		42.53333	1.58333	R	TRL	AD		00				0		1571	Europe/Andorra	1993-12-23
+3039327	Radonella	Radonella		42.48333	1.45	L	LCTY	AD		00				0		1195	Europe/Andorra	1993-12-23
+3039328	Rádio Andorra	Radio Andorra		42.5282	1.57019	S	STNR	AD		00				0		1418	Europe/Andorra	2011-04-19
+3039329	Racons	Racons		42.56667	1.58333	A	ADMD	AD		00				0		1919	Europe/Andorra	1993-12-23
+3039330	Pic de la Raconada de la Maiana	Pic de la Raconada de la Maiana	Pic de la Raconada de la Maiana	42.46667	1.61667	T	PK	AD		00				0		2448	Europe/Andorra	2011-11-05
+3039331	Clots de la Raconada de la Maiana	Clots de la Raconada de la Maiana		42.46667	1.6	T	CRQS	AD		00				0		2449	Europe/Andorra	1993-12-23
+3039332	Pic de Racofred	Pic de Racofred	Pic de Racofred,Pic de Racofret	42.6	1.45	T	PK	AD		00				0		2174	Europe/Andorra	2011-11-05
+3039333	Racó de l’Estany de Cabana Sorda	Raco de l'Estany de Cabana Sorda		42.61667	1.66667	L	LCTY	AD		00				0		2536	Europe/Andorra	1993-12-23
+3039334	Pleta del Racó	Pleta del Raco		42.61667	1.56667	L	GRAZ	AD		00				0		2228	Europe/Andorra	1993-12-23
+3039335	Pleta del Racó	Pleta del Raco		42.58333	1.45	L	GRAZ	AD		00				0		2156	Europe/Andorra	1993-12-23
+3039336	Canal del Racó	Canal del Raco		42.56667	1.48333	H	RVN	AD		00				0		1508	Europe/Andorra	1993-12-23
+3039337	Bassa del Racó	Bassa del Raco		42.61667	1.5	H	LK	AD		00				0		2390	Europe/Andorra	1993-12-23
+3039338	Pleta de la Rabassa	Pleta de la Rabassa		42.63333	1.55	L	GRAZ	AD		00				0		2053	Europe/Andorra	1993-12-23
+3039339	Carretera de la Rabassa	Carretera de la Rabassa		42.43333	1.51667	R	RD	AD		00				0		2031	Europe/Andorra	1993-12-23
+3039340	Canya de la Rabassa	Canya de la Rabassa		42.63333	1.55	S	CAVE	AD		00				0		2053	Europe/Andorra	1993-12-23
+3039341	Bosc de la Rabassa	Bosc de la Rabassa		42.4379	1.51425	V	FRST	AD		00				0		1990	Europe/Andorra	2011-04-19
+3039342	Solana del Querol	Solana del Querol		42.58333	1.53333	T	SLP	AD		00				0		1924	Europe/Andorra	1993-12-23
+3039343	Riu del Querol	Riu del Querol		42.58333	1.66667	H	STM	AD		00				0		2159	Europe/Andorra	1993-12-23
+3039344	Riu del Querol	Riu del Querol		42.58333	1.53333	H	STM	AD		00				0		1924	Europe/Andorra	1993-12-23
+3039345	Pleta del Querol	Pleta del Querol		42.6	1.66667	L	GRAZ	AD		00				0		1858	Europe/Andorra	1993-12-23
+3039346	Estanyó del Querol	Estanyo del Querol		42.61303	1.67019	H	LK	AD		00				0		2355	Europe/Andorra	2011-04-19
+3039347	Serrat de la Quera	Serrat de la Quera		42.51667	1.51667	T	RDGE	AD		00				0		1265	Europe/Andorra	1993-12-23
+3039348	Canal Gran de la Quera	Canal Gran de la Quera		42.45	1.46667	H	STM	AD		00				0		935	Europe/Andorra	1993-12-23
+3039349	Bosc de la Quera	Bosc de la Quera		42.51667	1.51667	V	FRST	AD		00				0		1265	Europe/Andorra	1993-12-23
+3039350	Roc del Quer	Roc del Quer		42.61667	1.55	T	SPUR	AD		00				0		2007	Europe/Andorra	1993-12-23
+3039351	Roc del Quer	Roc del Quer		42.55	1.51667	T	SPUR	AD		00				0		1397	Europe/Andorra	1993-12-23
+3039352	Roc del Quer	Roc del Quer		42.58333	1.48333	T	RK	AD		00				0		1809	Europe/Andorra	1993-12-23
+3039353	Roc del Quer	Roc del Quer		42.52798	1.60146	T	RK	AD		00				0		1888	Europe/Andorra	2011-04-19
+3039354	Roc del Quer	Roc del Quer		42.56667	1.6	T	CLF	AD		00				0		1655	Europe/Andorra	1993-12-23
+3039355	Roc de Quer	Roc de Quer		42.48333	1.46667	T	RK	AD		00				0		1148	Europe/Andorra	1993-12-23
+3039356	Planell del Quer	Planell del Quer		42.63333	1.56667	T	UPLD	AD		00				0		2394	Europe/Andorra	1993-12-23
+3039357	Canal del Quer	Canal del Quer		42.63333	1.55	H	RVN	AD		00				0		2053	Europe/Andorra	1993-12-23
+3039358	Canal del Quer	Canal del Quer		42.51667	1.6	H	RVN	AD		00				0		2085	Europe/Andorra	1993-12-23
+3039359	Bosc del Quer	Bosc del Quer		42.51667	1.6	V	FRST	AD		00				0		2085	Europe/Andorra	1993-12-23
+3039360	Solà del Quart de Nagol	Sola del Quart de Nagol		42.48333	1.51667	T	SLP	AD		00				0		2061	Europe/Andorra	1993-12-23
+3039361	Collet Purgat	Collet Purgat		42.46667	1.48333	T	PK	AD		00				0		1134	Europe/Andorra	1993-12-23
+3039363	Pont de Puntal	Pont de Puntal		42.61667	1.55	S	BDG	AD		00				0		2007	Europe/Andorra	1993-12-23
+3039364	Bosc de Puntal	Bosc de Puntal		42.63333	1.55	V	FRST	AD		00				0		2053	Europe/Andorra	1993-12-23
+3039365	Puntal	Puntal		42.63333	1.55	L	LCTY	AD		00				0		2053	Europe/Andorra	1993-12-23
+3039366	Vial dels Pujols	Vial dels Pujols		42.48333	1.48333	R	RD	AD		00				0		981	Europe/Andorra	1993-12-23
+3039367	Tarteres dels Pujols	Tarteres dels Pujols		42.48333	1.48333	T	TAL	AD		00				0		981	Europe/Andorra	1993-12-23
+3039368	Roc del Pujol	Roc del Pujol		42.46667	1.5	T	RK	AD		00				0		1383	Europe/Andorra	1993-12-23
+3039369	Pujant de Donges	Pujant de Donges		42.45	1.5	L	LCTY	AD		00				0		1614	Europe/Andorra	1993-12-23
+3039370	Puiol del Piu	Puiol del Piu		42.56667	1.5	P	PPL	AD		04				0		1636	Europe/Andorra	1993-12-23
+3039371	Borda del Puigcernal	Borda del Puigcernal		42.55	1.58333	S	HUT	AD		00				0		1499	Europe/Andorra	1993-12-23
+3039372	Pui d’Olivesa	Pui d'Olivesa		42.45	1.48333	L	LCTY	AD		00				0		1111	Europe/Andorra	1993-12-23
+3039373	Pui d’Encamp	Pui d'Encamp		42.53333	1.56667	L	LCTY	AD		00				0		1418	Europe/Andorra	1993-12-23
+3039374	Estany Primer	Estany Primer		42.63721	1.49019	H	LK	AD		05				0		2254	Europe/Andorra	2010-01-12
+3039375	Estany Primer	Estany Primer		42.61667	1.71667	H	LK	AD		00				0		2352	Europe/Andorra	1993-12-23
+3039376	Estany Primer	Estany Primer		42.51667	1.68333	H	LK	AD		00				0		2352	Europe/Andorra	1993-12-23
+3039377	Canal de la Presa	Canal de la Presa		42.58333	1.63333	H	CNL	AD		00				0		1722	Europe/Andorra	1993-12-23
+3039378	Canal de la Premsa	Canal de la Premsa		42.46667	1.48333	H	STM	AD		00				0		1134	Europe/Andorra	1993-12-23
+3039379	Canal Pregona	Canal Pregona		42.56667	1.48333	H	STM	AD		00				0		1508	Europe/Andorra	1993-12-23
+3039380	Canal Pregona	Canal Pregona		42.55	1.5	H	STM	AD		00				0		1292	Europe/Andorra	1993-12-23
+3039381	Torrent Pregó	Torrent Prego		42.53333	1.58333	H	STM	AD		00				0		1571	Europe/Andorra	1993-12-23
+3039382	Bosc dels Prats Sobirans	Bosc dels Prats Sobirans		42.51667	1.46667	V	FRST	AD		00				0		1840	Europe/Andorra	1993-12-23
+3039383	Planells dels Prats Nous	Planells dels Prats Nous		42.58333	1.48333	T	UPLD	AD		00				0		1809	Europe/Andorra	1993-12-23
+3039384	Bordes dels Prats Nous	Bordes dels Prats Nous		42.58333	1.48333	S	HUTS	AD		00				0		1809	Europe/Andorra	1993-12-23
+3039385	Riu de Prats	Riu de Prats		42.55	1.58333	H	STM	AD		00				0		1499	Europe/Andorra	1993-12-23
+3039386	Prats	Prats		42.56003	1.59396	P	PPL	AD		02				0		1677	Europe/Andorra	2007-04-16
+3039387	Solana de Prat Primer	Solana de Prat Primer		42.48333	1.55	T	SLP	AD		00				0		2233	Europe/Andorra	1993-12-23
+3039388	Planell de Prat Primer	Planell de Prat Primer		42.48333	1.55	T	UPLD	AD		00				0		2233	Europe/Andorra	1993-12-23
+3039389	Obaga de Prat Primer	Obaga de Prat Primer		42.48333	1.55	T	SLP	AD		00				0		2233	Europe/Andorra	1993-12-23
+3039390	Font de Prat Primer	Font de Prat Primer		42.48333	1.55	H	SPNG	AD		00				0		2233	Europe/Andorra	1993-12-23
+3039391	Collada de Prat Primer	Collada de Prat Primer		42.46667	1.55	T	PASS	AD		00				0		2341	Europe/Andorra	1993-12-23
+3039392	Clots de Prat Primer	Clots de Prat Primer		42.48333	1.55	H	RVN	AD		00				0		2233	Europe/Andorra	1993-12-23
+3039393	Prat Primer	Prat Primer		42.48333	1.55	A	ADMD	AD		00				0		2233	Europe/Andorra	1993-12-23
+3039394	Collada de Prat Porceller	Collada de Prat Porceller	Collada de Prat Porceller	42.46667	1.45	T	PASS	AD		00				0		1562	Europe/Andorra	2011-11-05
+3039395	Font del Prat de Roca	Font del Prat de Roca		42.56667	1.58333	H	SPNG	AD		00				0		1919	Europe/Andorra	1993-12-23
+3039396	Font del Prat dels Pollins	Font del Prat dels Pollins		42.56667	1.58333	H	SPNG	AD		00				0		1919	Europe/Andorra	1993-12-23
+3039397	Basers del Prat del Quart	Basers del Prat del Quart		42.61667	1.63333	T	CLF	AD		00				0		2331	Europe/Andorra	1993-12-23
+3039398	Font del Prat del Jep	Font del Prat del Jep	Font del Prat del Gep,Font del Prat del Jep	42.56667	1.58333	H	SPNG	AD	AD	00				0		1919	Europe/Andorra	2011-11-05
+3039399	Torrent del Prat del Gaspar	Torrent del Prat del Gaspar		42.53333	1.56667	H	STM	AD		00				0		1418	Europe/Andorra	1993-12-23
+3039400	Bosc del Prat de l’Estel	Bosc del Prat de l'Estel		42.53333	1.46667	V	FRST	AD		00				0		1846	Europe/Andorra	1993-12-23
+3039401	Riu del Prat del Comellar	Riu del Prat del Comellar		42.58333	1.65	H	STM	AD		00				0		1767	Europe/Andorra	1993-12-23
+3039402	Solana del Prat del Bosc	Solana del Prat del Bosc		42.58333	1.46667	T	SLP	AD		00				0		1643	Europe/Andorra	1993-12-23
+3039403	Riu del Prat del Bosc	Riu del Prat del Bosc		42.55	1.48333	H	STM	AD		00				0		1548	Europe/Andorra	1993-12-23
+3039404	Pont del Prat del Bosc	Pont del Prat del Bosc		42.53333	1.46667	S	BDG	AD		00				0		1846	Europe/Andorra	1993-12-23
+3039405	Bosc del Prat del Bosc	Bosc del Prat del Bosc		42.53333	1.46667	V	FRST	AD		00				0		1846	Europe/Andorra	1993-12-23
+3039406	Obagues del Prat de la Posella	Obagues del Prat de la Posella		42.48333	1.45	T	SLP	AD		00				0		1195	Europe/Andorra	1993-12-23
+3039407	Basera del Prat de la Farga	Basera del Prat de la Farga		42.48333	1.45	T	CLF	AD		00				0		1195	Europe/Andorra	1993-12-23
+3039408	Basers del Prat de la Creu	Basers del Prat de la Creu		42.6	1.63333	T	CLF	AD		00				0		1893	Europe/Andorra	1993-12-23
+3039409	Obaga dels Pradets	Obaga dels Pradets		42.48333	1.43333	T	SLP	AD		00				0		1938	Europe/Andorra	1993-12-23
+3039410	Roc dels Pous	Roc dels Pous		42.55	1.61667	T	RK	AD		00				0		2206	Europe/Andorra	1993-12-23
+3039411	Bosc dels Pous	Bosc dels Pous		42.55	1.48333	V	FRST	AD		00				0		1548	Europe/Andorra	1993-12-23
+3039412	Serrat del Pouet	Serrat del Pouet		42.55	1.51667	T	RDGE	AD		00				0		1397	Europe/Andorra	1993-12-23
+3039413	Canal del Pouet	Canal del Pouet		42.56667	1.53333	H	STM	AD		00				0		1669	Europe/Andorra	1993-12-23
+3039414	Costa del Pou	Costa del Pou		42.58333	1.58333	T	SLP	AD		00				0		1993	Europe/Andorra	1993-12-23
+3039415	Bosc de les Poselletes	Bosc de les Poselletes		42.55	1.45	V	FRST	AD		00				0		1788	Europe/Andorra	1993-12-23
+3039416	Bony de la Posella	Bony de la Posella		42.58333	1.48333	T	SPUR	AD		00				0		1809	Europe/Andorra	1993-12-23
+3039417	Posada dels Pastors	Posada dels Pastors		42.58333	1.48333	L	LCTY	AD		00				0		1809	Europe/Andorra	1993-12-23
+3039418	Font de la Posada	Font de la Posada		42.46667	1.45	H	SPNG	AD		00				0		1562	Europe/Andorra	1993-12-23
+3039419	Serrat de la Posa	Serrat de la Posa		42.55	1.66667	T	RDGE	AD		00				0		2224	Europe/Andorra	1993-12-23
+3039420	Turó del Port Vell	Turo del Port Vell		42.65	1.56667	T	PK	AD		00				0		2471	Europe/Andorra	1993-12-23
+3039421	Pic del Port Vell	Pic del Port Vell	Pic del Port Vell	42.57205	1.44341	T	PK	AD		00				0	2655	2305	Europe/Andorra	2011-02-09
+3039422	Canal del Port Vell	Canal del Port Vell		42.56667	1.45	H	STM	AD		00				0		2137	Europe/Andorra	1993-12-23
+3039423	Clot de Port Negre	Clot de Port Negre		42.46667	1.56667	H	RVN	AD		00				0		2365	Europe/Andorra	1993-12-23
+3039424	Basers de les Portes	Basers de les Portes		42.48333	1.5	T	CLF	AD		00				0		1631	Europe/Andorra	1993-12-23
+3039425	Portella de la Portelleta	Portella de la Portelleta		42.46667	1.65	T	PASS	AD		00				0		2700	Europe/Andorra	1993-12-23
+3039426	Tossa Plana de Lles	Tossa Plana de Lles	Pic de la Portelleta,Tosal Plane,Tossa Plana de Lles	42.46667	1.66667	T	PK	AD		00				0		2559	Europe/Andorra	2011-11-05
+3039427	Font de la Portelleta	Font de la Portelleta		42.46667	1.66667	H	SPNG	AD		00				0		2559	Europe/Andorra	1993-12-23
+3039428	Collada de la Portelleta	Collada de la Portelleta	Collada de la Portelleta	42.46667	1.66667	T	PASS	AD		00				0		2559	Europe/Andorra	2011-11-05
+3039429	Riu de les Portelles	Riu de les Portelles		42.61667	1.63333	H	STM	AD		00				0		2331	Europe/Andorra	1993-12-23
+3039430	Clots de la Portella de Setut	Clots de la Portella de Setut		42.46667	1.63333	T	CRQS	AD		00				0		2619	Europe/Andorra	1993-12-23
+3039431	Pleta de la Portella	Pleta de la Portella		42.56667	1.71667	L	GRAZ	AD		00				0		2219	Europe/Andorra	1993-12-23
+3039432	Collada de la Portella	Collada de la Portella		42.46667	1.63333	T	PASS	AD		00				0		2619	Europe/Andorra	1993-12-23
+3039433	Riu del Port Dret	Riu del Port Dret		42.6	1.46667	H	STM	AD		00				0		2421	Europe/Andorra	1993-12-23
+3039434	Estany del Port Dret	Estany del Port Dret		42.6	1.46667	H	LK	AD		00				0		2421	Europe/Andorra	1993-12-23
+3039435	Costa del Port Dret	Costa del Port Dret		42.58333	1.7	T	SLP	AD		00				0		2584	Europe/Andorra	1993-12-23
+3039436	Clots del Port Dret	Clots del Port Dret		42.56667	1.68333	H	RVN	AD		00				0		2340	Europe/Andorra	1993-12-23
+3039437	Camí del Port Dret	Cami del Port Dret		42.56667	1.66667	R	TRL	AD		00				0		1938	Europe/Andorra	1993-12-23
+3039439	Camí del Port de Setut	Cami del Port de Setut		42.46667	1.63333	R	TRL	AD		00				0		2619	Europe/Andorra	1993-12-23
+3039440	Basses del Port de Rat	Basses del Port de Rat		42.61667	1.48333	H	LKS	AD		05				0		2470	Europe/Andorra	2010-01-12
+3039441	Font del Port de Cabús	Font del Port de Cabus		42.55	1.41667	H	SPNG	AD		00				0		2105	Europe/Andorra	1993-12-23
+3039442	Planades del Port	Planades del Port		42.56667	1.45	T	UPLD	AD		00				0		2137	Europe/Andorra	1993-12-23
+3039443	Costa del Port	Costa del Port		42.56667	1.45	T	SLP	AD		00				0		2137	Europe/Andorra	1993-12-23
+3039444	Costa del Port	Costa del Port		42.53333	1.71667	T	SLP	AD		00				0		2400	Europe/Andorra	1993-12-23
+3039445	Clots del Port	Clots del Port		42.46667	1.58333	T	CRQS	AD		00				0		2367	Europe/Andorra	1993-12-23
+3039446	Clot del Port	Clot del Port		42.48333	1.65	H	RVN	AD		00				0		2658	Europe/Andorra	1993-12-23
+3039447	Canal del Port	Canal del Port		42.56667	1.45	H	STM	AD		00				0		2137	Europe/Andorra	1993-12-23
+3039448	Camí del Port	Cami del Port		42.48333	1.58333	R	TRL	AD		00				0		2349	Europe/Andorra	1993-12-23
+3039449	Roc del Porquer	Roc del Porquer		42.58333	1.45	T	SPUR	AD		00				0		2156	Europe/Andorra	1993-12-23
+3039450	Oratori del Pont d’Aixovall	Oratori del Pont d'Aixovall		42.48333	1.5	S	AMTH	AD		00				0		1631	Europe/Andorra	1993-12-23
+3039451	Canal del Pont	Canal del Pont		42.5	1.55	H	STM	AD		00				0		1566	Europe/Andorra	1993-12-23
+3039452	Riu Pollós	Riu Pollos		42.58333	1.46667	H	STM	AD		00				0		1643	Europe/Andorra	1993-12-23
+3039453	Bosc de la Pollentia	Bosc de la Pollentia		42.53333	1.5	V	FRST	AD		00				0		1357	Europe/Andorra	1993-12-23
+3039454	Roc del Poll	Roc del Poll		42.61667	1.53333	T	RK	AD		00				0		1609	Europe/Andorra	1993-12-23
+3039455	Roc de Podoïna	Roc de Podoina		42.45	1.5	T	RK	AD		00				0		1614	Europe/Andorra	1993-12-23
+3039456	Canal del Pletiu	Canal del Pletiu		42.5	1.58333	H	STM	AD		00				0		1888	Europe/Andorra	1993-12-23
+3039457	Serrat de les Pletes	Serrat de les Pletes		42.48333	1.43333	T	SPUR	AD		00				0		1938	Europe/Andorra	1993-12-23
+3039458	Serrat de la Pleta Vella	Serrat de la Pleta Vella		42.6	1.55	T	RDGE	AD		00				0		2298	Europe/Andorra	1993-12-23
+3039459	Canal de Pleta Mosquera	Canal de Pleta Mosquera		42.61667	1.51667	H	STM	AD		00				0		1716	Europe/Andorra	1993-12-23
+3039460	Canal de la Pleta dels Llacs	Canal de la Pleta dels Llacs		42.6	1.63333	H	STM	AD		00				0		1893	Europe/Andorra	1993-12-23
+3039461	Solana de la Pleta del Perro	Solana de la Pleta del Perro		42.53333	1.61667	T	SLP	AD		00				0		2237	Europe/Andorra	1993-12-23
+3039462	Canals de la Pleta del Llomar	Canals de la Pleta del Llomar		42.61667	1.56667	H	RVN	AD		00				0		2228	Europe/Andorra	1993-12-23
+3039463	Bony de la Pleta de Jan	Bony de la Pleta de Jan		42.61667	1.63333	T	MT	AD		00				0		2331	Europe/Andorra	1993-12-23
+3039464	Roc de la Pleta	Roc de la Pleta		42.6	1.46667	T	RK	AD		00				0		2421	Europe/Andorra	1993-12-23
+3039465	Costa de la Pleta	Costa de la Pleta		42.58333	1.45	T	SLP	AD		00				0		2156	Europe/Andorra	1993-12-23
+3039466	Bosc de la Pleta	Bosc de la Pleta		42.55	1.45	V	FRST	AD		00				0		1788	Europe/Andorra	1993-12-23
+3039467	Barraca de la Pleta	Barraca de la Pleta		42.56667	1.71667	S	HUT	AD		00				0		2219	Europe/Andorra	1993-12-23
+3039468	Camí dels Plans	Cami dels Plans		42.58333	1.61667	R	TRL	AD		00				0		1707	Europe/Andorra	1993-12-23
+3039469	Camí dels Plans	Cami dels Plans		42.53333	1.51667	R	TRL	AD		00				0		1361	Europe/Andorra	1993-12-23
+3039470	Bosc dels Plans	Bosc dels Plans		42.58333	1.63333	V	FRST	AD		00				0		1722	Europe/Andorra	1993-12-23
+3039471	Bordes dels Plans	Bordes dels Plans		42.53333	1.51667	S	FRM	AD		00				0		1361	Europe/Andorra	1993-12-23
+3039472	Obaga dels Plannels de la Regalíssia	Obaga dels Plannels de la Regalissia		42.48333	1.41667	T	SLP	AD		00				0		1920	Europe/Andorra	1993-12-23
+3039473	Planes de Fels	Planes de Fels		42.58333	1.53333	L	LCTY	AD		00				0		1924	Europe/Andorra	1993-12-23
+3039474	Solana de les Planes	Solana de les Planes		42.56667	1.53333	T	SLP	AD		00				0		1669	Europe/Andorra	1993-12-23
+3039475	Riu de les Planes	Riu de les Planes		42.63333	1.5	H	STM	AD		00				0		1979	Europe/Andorra	1993-12-23
+3039476	Pleta de les Planes	Pleta de les Planes		42.65	1.5	L	GRAZ	AD		00				0		2455	Europe/Andorra	1993-12-23
+3039477	Pic de l' Albeille	Pic de l' Albeille	Pic de les Planes	42.6457	1.49929	T	RDGE	AD	FR,AD	07				0		2542	Europe/Andorra	2007-03-04
+3039478	Les Planes	Les Planes		42.56667	1.55	T	UPLD	AD		00				0		1996	Europe/Andorra	1993-12-23
+3039479	Collet de les Planes	Collet de les Planes		42.56667	1.53333	T	SPUR	AD		00				0		1669	Europe/Andorra	1993-12-23
+3039480	Collada de les Planes	Collada de les Planes		42.65	1.5	T	PASS	AD		00				0		2455	Europe/Andorra	1993-12-23
+3039481	Bosc de les Planes	Bosc de les Planes		42.51667	1.6	V	FRST	AD		00				0		2085	Europe/Andorra	1993-12-23
+3039482	Bony de les Planes	Bony de les Planes		42.55	1.51667	T	SPUR	AD		00				0		1397	Europe/Andorra	1993-12-23
+3039483	Serrat dels Planells Grans	Serrat dels Planells Grans		42.53333	1.53333	T	RDGE	AD		00				0		1521	Europe/Andorra	1993-12-23
+3039484	Cabana dels Planells de Rialb	Cabana dels Planells de Rialb		42.65	1.55	S	HUT	AD		00				0		2181	Europe/Andorra	1993-12-23
+3039485	Planells de Rialb	Planells de Rialb		42.65	1.55	L	LCTY	AD		00				0		2181	Europe/Andorra	1993-12-23
+3039486	Riu dels Planells de Caraup	Riu dels Planells de Caraup		42.6	1.63333	H	STM	AD		00				0		1893	Europe/Andorra	1993-12-23
+3039487	Planells d’Arcalís	Planells d'Arcalis		42.63333	1.5	L	LCTY	AD		00				0		1979	Europe/Andorra	1993-12-23
+3039488	Serrat del Planell Lluent	Serrat del Planell Lluent		42.56667	1.51667	T	RDGE	AD		00				0		1500	Europe/Andorra	1993-12-23
+3039489	Bony del Planell Gran	Bony del Planell Gran		42.63333	1.55	T	SPUR	AD		00				0		2053	Europe/Andorra	1993-12-23
+3039490	Bosc de Planavilla	Bosc de Planavilla		42.55	1.68333	V	FRST	AD		00				0		2254	Europe/Andorra	1993-12-23
+3039491	Planavilla	Planavilla		42.55	1.68333	L	CLG	AD		00				0		2254	Europe/Andorra	1993-12-23
+3039492	Bosc de la Planassa	Bosc de la Planassa		42.55	1.5	V	FRST	AD		00				0		1292	Europe/Andorra	1993-12-23
+3039493	Bosc de Plana en Blanca	Bosc de Plana en Blanca		42.55	1.56667	V	FRST	AD		00				0		1828	Europe/Andorra	1993-12-23
+3039494	Tarteres de Plana de Gral	Tarteres de Plana de Gral		42.58333	1.48333	T	TAL	AD		00				0		1809	Europe/Andorra	1993-12-23
+3039495	Tosa Plana	Tosa Plana		42.46667	1.6	T	UPLD	AD		00				0		2449	Europe/Andorra	1993-12-23
+3039496	Torrent de la Plana	Torrent de la Plana		42.53333	1.6	H	STM	AD		00				0		1888	Europe/Andorra	1993-12-23
+3039497	Serra Plana	Serra Plana		42.58333	1.6	T	SPUR	AD		00				0		1828	Europe/Andorra	1993-12-23
+3039498	Serra Plana	Serra Plana		42.56667	1.48333	T	MT	AD		00				0		1508	Europe/Andorra	1993-12-23
+3039499	Sierra Plana	Sierra Plana	Serra Plana,Sierra Plana	42.48333	1.43333	T	MT	AD		00				0		1938	Europe/Andorra	2011-11-05
+3039500	Cortal de la Plana	Cortal de la Plana		42.48333	1.53333	S	HUT	AD		00				0		2255	Europe/Andorra	1993-12-23
+3039501	Coll de la Plana	Coll de la Plana		42.45	1.5	T	SPUR	AD		00				0		1614	Europe/Andorra	1993-12-23
+3039502	Camí de la Plana	Cami de la Plana		42.48333	1.55	R	TRL	AD		00				0		2233	Europe/Andorra	1993-12-23
+3039503	Bosquet de la Plana	Bosquet de la Plana		42.5	1.53333	V	FRST	AD		00				0		1574	Europe/Andorra	1993-12-23
+3039504	Bosc de la Plana	Bosc de la Plana		42.55	1.55	V	FRST	AD		00				0		2097	Europe/Andorra	1993-12-23
+3039505	Bordes de la Plana	Bordes de la Plana		42.53333	1.6	S	HUTS	AD		00				0		1888	Europe/Andorra	1993-12-23
+3039506	Borda de la Plana	Borda de la Plana		42.55	1.55	S	HUTS	AD		00				0		2097	Europe/Andorra	1993-12-23
+3039507	Barranc de la Plana	Barranc de la Plana		42.55	1.55	H	STM	AD		00				0		2097	Europe/Andorra	1993-12-23
+3039508	Serrat del Pla Morell	Serrat del Pla Morell		42.53333	1.53333	T	RDGE	AD		00				0		1521	Europe/Andorra	1993-12-23
+3039509	Torrent de Plamanera	Torrent de Plamanera		42.53333	1.56667	H	STM	AD		00				0		1418	Europe/Andorra	1993-12-23
+3039510	Bosc del Pla de Rodó	Bosc del Pla de Rodo		42.55	1.43333	V	FRST	AD		00				0		1949	Europe/Andorra	1993-12-23
+3039511	Bosc del Pla de Miretes	Bosc del Pla de Miretes		42.53333	1.48333	V	FRST	AD		00				0		1677	Europe/Andorra	1993-12-23
+3039512	Pic del Pla de l’Ingla	Pic del Pla de l'Ingla		42.48333	1.63333	T	PK	AD		00				0		2296	Europe/Andorra	1993-12-23
+3039513	Pla de l’Ingla	Pla de l'Ingla		42.48333	1.63333	A	ADMD	AD		00				0		2296	Europe/Andorra	1993-12-23
+3039514	Riu del Pla de l’Estany	Riu del Pla de l'Estany		42.58333	1.46667	H	STM	AD		00				0		1643	Europe/Andorra	1993-12-23
+3039515	Pleta del Pla de l’Estany	Pleta del Pla de l'Estany		42.58333	1.46667	L	GRAZ	AD		00				0		1643	Europe/Andorra	1993-12-23
+3039516	Pic des Bareytes	Pic des Bareytes	Pic del Pla de l'Estany,Pic del Pla de l’Estany,Pic des Bareytes	42.6	1.46667	T	PK	AD		00				0		2421	Europe/Andorra	2011-11-05
+3039517	Estret del Pla de l’Estany	Estret del Pla de l'Estany		42.6	1.45	T	PASS	AD		00				0		2174	Europe/Andorra	1993-12-23
+3039518	Pla de l’Estany	Pla de l'Estany		42.6	1.45	A	ADMD	AD		00				0		2174	Europe/Andorra	1993-12-23
+3039519	Camí del Pla de les Pedres	Cami del Pla de les Pedres		42.53333	1.68333	R	TRL	AD		00				0		2322	Europe/Andorra	1993-12-23
+3039520	Camí del Pla del Bosc	Cami del Pla del Bosc		42.53333	1.61667	R	TRL	AD		00				0		2237	Europe/Andorra	1993-12-23
+3039521	Bosc del Pla de la Cot	Bosc del Pla de la Cot		42.53333	1.46667	V	FRST	AD		00				0		1846	Europe/Andorra	1993-12-23
+3039522	Grau de les Places	Grau de les Places		42.55	1.46667	T	SLP	AD		00				0		1585	Europe/Andorra	1993-12-23
+3039523	Pleta de Pixolell	Pleta de Pixolell		42.58333	1.63333	L	GRAZ	AD		00				0		1722	Europe/Andorra	1993-12-23
+3039524	Costes de Pixolell	Costes de Pixolell		42.58333	1.63333	T	SLP	AD		00				0		1722	Europe/Andorra	1993-12-23
+3039525	Pont de la Pixistella	Pont de la Pixistella		42.56667	1.5	S	BDG	AD		00				0		1636	Europe/Andorra	1993-12-23
+3039526	Obac de la Pixistella	Obac de la Pixistella		42.55	1.5	T	SLP	AD		00				0		1292	Europe/Andorra	1993-12-23
+3039527	Canal de la Pixistella	Canal de la Pixistella		42.55	1.5	H	STM	AD		00				0		1292	Europe/Andorra	1993-12-23
+3039528	Bosc de la Pixistella	Bosc de la Pixistella		42.55	1.48333	V	FRST	AD		00				0		1548	Europe/Andorra	1993-12-23
+3039529	Font Pixadera	Font Pixadera		42.5	1.56667	H	SPNG	AD		00				0		1776	Europe/Andorra	1993-12-23
+3039530	Roca del Pisó	Roca del Piso		42.53333	1.63333	T	RK	AD		00				0		2360	Europe/Andorra	1993-12-23
+3039531	Borda del Pirot	Borda del Pirot		42.58333	1.65	S	HUT	AD		00				0		1767	Europe/Andorra	1993-12-23
+3039532	Pirineu	Pirineu		42.51667	1.55	L	LCTY	AD		00				0		1322	Europe/Andorra	1993-12-23
+3039533	Bosc de la Pinosa de Llumeneres	Bosc de la Pinosa de Llumeneres		42.46667	1.51667	V	FRST	AD		00				0		1985	Europe/Andorra	1993-12-23
+3039534	Bosc de la Pinosa	Bosc de la Pinosa		42.6	1.68333	V	FRST	AD		00				0		2089	Europe/Andorra	1993-12-23
+3039535	Bosc de la Pinosa	Bosc de la Pinosa		42.45	1.5	V	FRST	AD		00				0		1614	Europe/Andorra	1993-12-23
+3039536	Serrat Pinós	Serrat Pinos		42.55	1.68333	T	MT	AD		00				0		2254	Europe/Andorra	1993-12-23
+3039537	Collada de Pimes	Collada de Pimes		42.42951	1.54658	T	PASS	AD		00				0		2186	Europe/Andorra	2011-04-19
+3039538	Canal del Pi Gros	Canal del Pi Gros		42.5	1.46667	H	STM	AD		00				0		1678	Europe/Andorra	1993-12-23
+3039539	Borda del Piedro	Borda del Piedro		42.58333	1.63333	S	HUT	AD		00				0		1722	Europe/Andorra	1993-12-23
+3039540	Bosc del Pi de Montsalla	Bosc del Pi de Montsalla		42.53333	1.48333	V	FRST	AD		00				0		1677	Europe/Andorra	1993-12-23
+3039541	Camí del Pi de la Creu	Cami del Pi de la Creu		42.55	1.6	R	TRL	AD		00				0		2210	Europe/Andorra	1993-12-23
+3039542	Canal dels Picons	Canal dels Picons		42.56667	1.5	H	STM	AD		00				0		1636	Europe/Andorra	1993-12-23
+3039543	Bosc del Picó	Bosc del Pico		42.5	1.55	V	FRST	AD		00				0		1566	Europe/Andorra	1993-12-23
+3039544	Basers del Pic de la Cabaneta	Basers del Pic de la Cabaneta		42.61667	1.6	T	CLF	AD		00				0		2528	Europe/Andorra	1993-12-23
+3039545	Font Picadora	Font Picadora		42.56667	1.56667	H	SPNG	AD		00				0		2089	Europe/Andorra	1993-12-23
+3039546	Canal de la Pica	Canal de la Pica		42.5	1.5	H	STM	AD		00				0		1135	Europe/Andorra	1993-12-23
+3039547	Bony de la Pica	Bony de la Pica	Bony de la Pica,Pic d' Os,Pic d’ Ós,Pico de Ancla,Pico de Anclá	42.5	1.45	T	MT	AD		00				0		1840	Europe/Andorra	2011-11-05
+3039548	Basses del Pic	Basses del Pic		42.61667	1.61667	H	LKS	AD		00				0		2352	Europe/Andorra	1993-12-23
+3039549	Bosc del Peu dels Pessons	Bosc del Peu dels Pessons		42.51667	1.68333	V	FRST	AD		00				0		2352	Europe/Andorra	1993-12-23
+3039550	Font dels Pets	Font dels Pets		42.58333	1.48333	H	SPNG	AD		00				0		1809	Europe/Andorra	1993-12-23
+3039551	Coll Petit	Coll Petit	Coll Petit,Collado Pequeno,Collado Pequeño	42.56498	1.44248	T	PASS	AD		00				0		2408	Europe/Andorra	2011-11-05
+3039552	Riu dels Pessons	Riu dels Pessons		42.51667	1.7	H	STM	AD		00				0		2435	Europe/Andorra	1993-12-23
+3039553	Pic dels Pessons	Pic dels Pessons	Pic de Pessons,Pic dels Pessons,Pic des Pessons	42.50832	1.6585	T	PK	AD		00				0		2727	Europe/Andorra	2011-11-05
+3039554	Collada dels Pessons	Collada dels Pessons		42.5	1.65	T	PASS	AD		00				0		2542	Europe/Andorra	1993-12-23
+3039555	Pleta dels Pescadors	Pleta dels Pescadors		42.48333	1.65	L	GRAZ	AD		00				0		2658	Europe/Andorra	1993-12-23
+3039556	Pesada de Pal	Pesada de Pal		42.56667	1.48333	L	LCTY	AD		00				0		1508	Europe/Andorra	1993-12-23
+3039557	Pont de Pesada	Pont de Pesada		42.56667	1.48333	S	BDG	AD		00				0		1508	Europe/Andorra	1993-12-23
+3039558	Canal de Pesada	Canal de Pesada		42.56667	1.48333	H	STM	AD		00				0		1508	Europe/Andorra	1993-12-23
+3039559	Basera de Pesada	Basera de Pesada		42.56667	1.48333	T	CLF	AD		00				0		1508	Europe/Andorra	1993-12-23
+3039560	Pesada	Pesada		42.56667	1.48333	T	SLP	AD		00				0		1508	Europe/Andorra	1993-12-23
+3039561	Roc de Persoma	Roc de Persoma		42.48333	1.48333	T	RK	AD		00				0		981	Europe/Andorra	1993-12-23
+3039562	Plana Perdiguera	Plana Perdiguera		42.55	1.45	T	UPLD	AD		00				0		1788	Europe/Andorra	1993-12-23
+3039563	Pic de Percanela	Pic de Percanela		42.58915	1.49666	T	PK	AD		00				0		2089	Europe/Andorra	2011-04-19
+3039564	Bordes de Percanela	Bordes de Percanela		42.5825	1.48809	S	FRM	AD		00				0		2019	Europe/Andorra	2011-04-19
+3039565	Percanela	Percanela	Coma de Percanela,Loma de Percanela,Percanela	42.58333	1.48333	A	ADMD	AD	AD	00				0		1809	Europe/Andorra	2011-11-05
+3039566	Camí de Per Baix	Cami de Per Baix		42.55	1.68333	R	TRL	AD		00				0		2254	Europe/Andorra	1993-12-23
+3039567	Riu de Perafita	Riu de Perafita		42.49733	1.55811	H	STM	AD		00				0		1566	Europe/Andorra	2011-04-19
+3039568	Pleta de Perafita	Pleta de Perafita		42.48333	1.58333	L	GRAZ	AD		00				0		2349	Europe/Andorra	1993-12-23
+3039569	Planells de Perafita	Planells de Perafita		42.48333	1.58333	T	UPLD	AD		00				0		2349	Europe/Andorra	1993-12-23
+3039570	Estanys de Perafita	Estanys de Perafita		42.47027	1.58958	H	LKS	AD		00				0		2518	Europe/Andorra	2011-04-19
+3039571	Costa de Perafita	Costa de Perafita		42.48333	1.58333	T	SLP	AD		00				0		2349	Europe/Andorra	1993-12-23
+3039572	Camí de Perafita	Cami de Perafita		42.5	1.56667	R	TRL	AD		00				0		1776	Europe/Andorra	1993-12-23
+3039573	Cabana de Perafita	Cabana de Perafita		42.48333	1.58333	S	HUT	AD		00				0		2349	Europe/Andorra	1993-12-23
+3039574	Perafita	Perafita		42.46667	1.58333	A	ADMD	AD		00				0		2367	Europe/Andorra	1993-12-23
+3039575	Canal de la Pera	Canal de la Pera		42.56667	1.48333	H	RVN	AD		00				0		1508	Europe/Andorra	1993-12-23
+3039576	Roc de la Penya	Roc de la Penya		42.53333	1.55	T	RK	AD		00				0		1344	Europe/Andorra	1993-12-23
+3039577	Costa Pentinada	Costa Pentinada		42.48333	1.53333	T	SLP	AD		00				0		2255	Europe/Andorra	1993-12-23
+3039578	Riu de la Peguera	Riu de la Peguera		42.45	1.51667	H	STM	AD		00				0		1790	Europe/Andorra	1993-12-23
+3039579	Conreu de la Peguera	Conreu de la Peguera		42.45	1.53333	V	CULT	AD		00				0		1859	Europe/Andorra	1993-12-23
+3039580	Carretera de la Peguera	Carretera de la Peguera		42.46667	1.55	R	RD	AD		00				0		2341	Europe/Andorra	1993-12-23
+3039581	Bosc de la Peguera	Bosc de la Peguera		42.46321	1.52655	V	FRST	AD		00				0		2068	Europe/Andorra	2011-04-19
+3039582	Bordes de la Peguera	Bordes de la Peguera		42.45	1.53333	S	HUTS	AD		00				0		1859	Europe/Andorra	1993-12-23
+3039583	Serrat de les Pedrusques	Serrat de les Pedrusques		42.6	1.5	T	SPUR	AD		00				0		1923	Europe/Andorra	1993-12-23
+3039584	Torrent Pedrós	Torrent Pedros		42.45	1.48333	H	STM	AD		00				0		1111	Europe/Andorra	1993-12-23
+3039585	Bosc de Pedres Blanques	Bosc de Pedres Blanques		42.53333	1.48333	V	FRST	AD		00				0		1677	Europe/Andorra	1993-12-23
+3039586	Pla de les Pedres	Pla de les Pedres		42.55	1.66667	T	UPLD	AD		00				0		2224	Europe/Andorra	1993-12-23
+3039587	Pont Pedregat	Pont Pedregat		42.58333	1.48333	S	BDG	AD		00				0		1809	Europe/Andorra	1993-12-23
+3039588	Canal de Pedra Plana	Canal de Pedra Plana		42.51667	1.5	H	STM	AD		00				0		1688	Europe/Andorra	1993-12-23
+3039589	Corral de Pedra	Corral de Pedra		42.56667	1.7	L	GRAZ	AD		00				0		2375	Europe/Andorra	1993-12-23
+3039590	Corral de Pedra	Corral de Pedra		42.56667	1.65	L	GRAZ	AD		00				0		1988	Europe/Andorra	1993-12-23
+3039591	Canal de la Peca Rodona	Canal de la Peca Rodona		42.53333	1.48333	H	STM	AD		00				0		1677	Europe/Andorra	1993-12-23
+3039592	Bosc de Paulelles	Bosc de Paulelles		42.53333	1.53333	V	FRST	AD		00				0		1521	Europe/Andorra	1993-12-23
+3039593	Borda de Paulelles	Borda de Paulelles		42.53333	1.55	S	HUT	AD		00				0		1344	Europe/Andorra	1993-12-23
+3039594	Passos dels Estanys	Passos dels Estanys		42.6	1.6	L	LCTY	AD		00				0		2143	Europe/Andorra	1993-12-23
+3039595	Passos de la Tarterosa	Passos de la Tarterosa		42.6	1.65	L	LCTY	AD		00				0		2131	Europe/Andorra	1993-12-23
+3039596	Canal del Passatorrents	Canal del Passatorrents		42.43333	1.48333	H	STM	AD		00				0		1228	Europe/Andorra	1993-12-23
+3039597	Coll Passader	Coll Passader		42.55	1.5	T	PK	AD		00				0		1292	Europe/Andorra	1993-12-23
+3039598	Riu del Pas Mal	Riu del Pas Mal		42.53333	1.65	H	STM	AD		00				0		2508	Europe/Andorra	1993-12-23
+3039599	Costa del Pas del Monjo	Costa del Pas del Monjo		42.63333	1.56667	T	SLP	AD		00				0		2394	Europe/Andorra	1993-12-23
+3039600	Pas del Monjo	Pas del Monjo		42.63333	1.55	L	LCTY	AD		00				0		2053	Europe/Andorra	1993-12-23
+3039601	Bosc del Pas de la Clau	Bosc del Pas de la Clau		42.51667	1.61667	V	FRST	AD		00				0		2254	Europe/Andorra	1993-12-23
+3039602	Solana del Pas de la Casa	Solana del Pas de la Casa		42.53333	1.73333	T	SLP	AD		00				0		2300	Europe/Andorra	1993-12-23
+3039603	Riu del Pas de la Casa	Riu del Pas de la Casa	Riu del Pas de la Casa	42.56667	1.75	H	STMX	AD		00				0		1923	Europe/Andorra	2011-11-05
+3039604	Pas de la Casa	Pas de la Casa	Pas de la Kasa,ÐŸÐ°Ñ Ð´Ðµ ла КаÑа	42.54277	1.73361	P	PPL	AD		03				2363	2050	2230	Europe/Andorra	2008-06-09
+3039605	Pas de la Casa	Pas de la Casa		42.53333	1.71667	A	ADMD	AD		00				0		2400	Europe/Andorra	1993-12-23
+3039606	Partida d’Ensucaranes	Partida d'Ensucaranes		42.51667	1.55	L	LCTY	AD		00				0		1322	Europe/Andorra	1993-12-23
+3039607	Partida de l’Any de la Part	Partida de l'Any de la Part		42.55	1.53333	A	ADMD	AD		00				0		1593	Europe/Andorra	1993-12-23
+3039608	Partida de la Grella	Partida de la Grella		42.51667	1.51667	A	ADMD	AD		00				0		1265	Europe/Andorra	1993-12-23
+3039609	Borda de les Pardines	Borda de les Pardines		42.53333	1.6	S	FRM	AD		00				0		1888	Europe/Andorra	1993-12-23
+3039610	Tossal de la Pardina	Tossal de la Pardina		42.5	1.48333	T	SPUR	AD		00				0		1316	Europe/Andorra	1993-12-23
+3039611	Bosc del Pardal	Bosc del Pardal		42.55	1.5	V	FRST	AD		00				0		1292	Europe/Andorra	1993-12-23
+3039612	Riu de la Palomera	Riu de la Palomera		42.56667	1.78333	H	STM	AD		00				0		1680	Europe/Andorra	1993-12-23
+3039613	Cap de la Palomera	Cap de la Palomera	Cap de la Palomera	42.58333	1.78333	T	PK	AD		00				0		1694	Europe/Andorra	2011-11-05
+3039614	Pont de Palomer	Pont de Palomer		42.56667	1.48333	S	BDG	AD		00				0		1508	Europe/Andorra	1993-12-23
+3039615	Pic de Palomer	Pic de Palomer		42.56667	1.48333	T	PK	AD		00				0		1508	Europe/Andorra	1993-12-23
+3039616	Obaga de Palomer	Obaga de Palomer		42.56667	1.48333	T	SLP	AD		00				0		1508	Europe/Andorra	1993-12-23
+3039617	Canal de Palomer	Canal de Palomer		42.56667	1.48333	H	STM	AD		00				0		1508	Europe/Andorra	1993-12-23
+3039618	Callissa de Palomer	Callissa de Palomer		42.56667	1.48333	T	GRGE	AD		00				0		1508	Europe/Andorra	1993-12-23
+3039619	Palomer	Palomer		42.56667	1.48333	A	ADMD	AD		00				0		1508	Europe/Andorra	1993-12-23
+3039620	Feixa Pallola	Feixa Pallola		42.43333	1.46667	V	CULT	AD		00				0		1113	Europe/Andorra	1993-12-23
+3039621	Serrat Pallero	Serrat Pallero		42.45	1.45	T	SPUR	AD		00				0		1482	Europe/Andorra	1993-12-23
+3039622	Prat de Paleta	Prat de Paleta		42.48333	1.6	L	GRAZ	AD		00				0		2250	Europe/Andorra	1993-12-23
+3039623	Serrat de la Palanqueta	Serrat de la Palanqueta		42.55	1.6	T	RDGE	AD		00				0		2210	Europe/Andorra	1993-12-23
+3039624	Riu de la Palanqueta	Riu de la Palanqueta		42.55	1.6	H	STM	AD		00				0		2210	Europe/Andorra	1993-12-23
+3039625	Pont de les Palanques	Pont de les Palanques		42.55	1.51667	S	BDG	AD		00				0		1397	Europe/Andorra	1993-12-23
+3039626	Planell de la Palanca	Planell de la Palanca		42.55	1.68333	T	UPLD	AD		00				0		2254	Europe/Andorra	1993-12-23
+3039627	Pic de la Pala de Coll Carnisser	Pic de la Pala de Coll Carnisser		42.6	1.48333	T	PK	AD		00				0		2441	Europe/Andorra	1993-12-23
+3039628	Pic de la Pala Alta	Pic de la Pala Alta		42.6	1.63333	T	PK	AD		00				0		1893	Europe/Andorra	1993-12-23
+3039629	Solà de Pal	Sola de Pal		42.55	1.46667	T	SLP	AD		00				0		1585	Europe/Andorra	1993-12-23
+3039630	Riu de Pal	Riu de Pal		42.56159	1.49544	H	STM	AD		00				0		1430	Europe/Andorra	2011-04-19
+3039631	Pont de Pal	Pont de Pal		42.55	1.46667	S	BDG	AD		00				0		1585	Europe/Andorra	1993-12-23
+3039632	Carretera de Pal	Carretera de Pal		42.55	1.48333	R	RD	AD		00				0		1548	Europe/Andorra	1993-12-23
+3039633	Bosc de Pal	Bosc de Pal		42.53333	1.46667	V	FRST	AD		00				0		1846	Europe/Andorra	1993-12-23
+3039634	Pal	Pal	Pal	42.55	1.48333	P	PPL	AD		04				0		1548	Europe/Andorra	2011-11-05
+3039635	Serra de Padern	Serra de Padern		42.53333	1.55	T	RDGE	AD		00				0		1344	Europe/Andorra	1993-12-23
+3039636	Riu de Padern	Riu de Padern		42.52834	1.52213	H	STM	AD		00				0		1361	Europe/Andorra	2011-04-19
+3039637	Pic de Padern	Pic de Padern		42.52429	1.54697	T	PK	AD		00				0		1290	Europe/Andorra	2011-04-19
+3039638	Bosc de Padern	Bosc de Padern		42.53333	1.53333	V	FRST	AD		00				0		1521	Europe/Andorra	1993-12-23
+3039639	Coll Pa	Coll Pa		42.55	1.43333	T	PK	AD		00				0		1949	Europe/Andorra	1993-12-23
+3039640	Coll Pa	Coll Pa		42.48333	1.56667	T	PASS	AD		00				0		2231	Europe/Andorra	1993-12-23
+3039641	Canal de l’ Ovella Morta	Canal de l' Ovella Morta		42.48333	1.58333	H	STM	AD		00				0		2349	Europe/Andorra	1993-12-23
+3039642	Riu de l’ Ovella	Riu de l' Ovella		42.53333	1.6	H	STM	AD		00				0		1888	Europe/Andorra	1993-12-23
+3039643	Port de l’ Ovella	Port de l' Ovella	Port de L'Ovella,Port de L’Ovella,Port de l' Ovella,Port de l’ Ovella	42.55	1.43333	T	PASS	AD		00				0		1949	Europe/Andorra	2011-11-05
+3039644	Bosc de l’ Ovella	Bosc de l' Ovella		42.53333	1.6	V	FRST	AD		00				0		1888	Europe/Andorra	1993-12-23
+3039645	Font de l’ Óssa	Font de l' Ossa		42.51667	1.48333	H	SPNG	AD		00				0		1839	Europe/Andorra	1993-12-23
+3039646	Cova de l’ Óssa	Cova de l' Ossa		42.46667	1.48333	S	CAVE	AD		00				0		1134	Europe/Andorra	1993-12-23
+3039647	Cova de l’ Óssa	Cova de l' Ossa		42.45	1.48333	S	CAVE	AD		00				0		1111	Europe/Andorra	1993-12-23
+3039648	Canya de l’ Óssa	Canya de l' Ossa		42.56667	1.51667	S	CAVE	AD		00				0		1500	Europe/Andorra	1993-12-23
+3039649	Canal de l’ Óssa	Canal de l' Ossa		42.5	1.63333	H	STM	AD		00				0		2545	Europe/Andorra	1993-12-23
+3039650	Canal de l’ Óssa	Canal de l' Ossa		42.58333	1.46667	H	RVN	AD		00				0		1643	Europe/Andorra	1993-12-23
+3039651	Carretera d’ Ós de Civís	Carretera d' Os de Civis		42.48333	1.46667	R	RD	AD		00				0		1148	Europe/Andorra	1993-12-23
+3039652	Canal de l’ Osca de Migdia	Canal de l' Osca de Migdia		42.46667	1.46667	H	STM	AD		00				0		1340	Europe/Andorra	1993-12-23
+3039653	Clots de l’ Ós	Clots de l' Os		42.58333	1.68333	H	RVN	AD		00				0		2294	Europe/Andorra	1993-12-23
+3039654	Clot de l’ Ós	Clot de l' Os		42.58333	1.66667	H	RVN	AD		00				0		2159	Europe/Andorra	1993-12-23
+3039655	Tosa d’ Ortafà	Tosa d' Ortafa		42.56667	1.71667	T	UPLD	AD		00				0		2219	Europe/Andorra	1993-12-23
+3039656	Tarteres d’ Ortafà	Tarteres d' Ortafa		42.56667	1.71667	T	TAL	AD		00				0		2219	Europe/Andorra	1993-12-23
+3039657	Font d’ Ortafà	Font d' Ortafa		42.56667	1.71667	H	SPNG	AD		00				0		2219	Europe/Andorra	1993-12-23
+3039658	Collet d’ Ortafà	Collet d' Ortafa		42.56667	1.7	T	PASS	AD		00				0		2375	Europe/Andorra	1993-12-23
+3039659	Clots d’ Ortafà	Clots d' Ortafa		42.55	1.71667	H	RVN	AD		00				0		2192	Europe/Andorra	1993-12-23
+3039660	Canals d’ Ortafà	Canals d' Ortafa		42.56667	1.7	H	RVN	AD		00				0		2375	Europe/Andorra	1993-12-23
+3039661	Ortafà	Ortafa		42.56667	1.71667	A	ADMD	AD		00				0		2219	Europe/Andorra	1993-12-23
+3039662	Bony de l’ Orri Vell	Bony de l' Orri Vell		42.53333	1.63333	T	SPUR	AD		00				0		2360	Europe/Andorra	1993-12-23
+3039663	Riu dels Orris	Riu dels Orris		42.48333	1.63333	H	STM	AD		00				0		2296	Europe/Andorra	1993-12-23
+3039664	Prats dels Orris	Prats dels Orris		42.53333	1.63333	L	GRAZ	AD		00				0		2360	Europe/Andorra	1993-12-23
+3039665	Pleta dels Orris	Pleta dels Orris		42.53333	1.63333	L	GRAZ	AD		00				0		2360	Europe/Andorra	1993-12-23
+3039666	Barraca de l’ Orri de Rusca	Barraca de l' Orri de Rusca		42.55	1.68333	S	HUT	AD		00				0		2254	Europe/Andorra	1993-12-23
+3039667	Bosc de l’ Orri del Call	Bosc de l' Orri del Call		42.6	1.65	V	FRST	AD		00				0		2131	Europe/Andorra	1993-12-23
+3039668	Serrat de l’ Orri de Gastó	Serrat de l' Orri de Gasto		42.48333	1.46667	T	SPUR	AD		00				0		1148	Europe/Andorra	1993-12-23
+3039669	Serrat de l’ Orri	Serrat de l' Orri		42.58333	1.66667	T	SLP	AD		00				0		2159	Europe/Andorra	1993-12-23
+3039670	Pont de l’ Orri	Pont de l' Orri		42.58333	1.66667	S	BDG	AD		00				0		2159	Europe/Andorra	1993-12-23
+3039671	Obaga de l’ Orri	Obaga de l' Orri		42.46667	1.45	T	SLP	AD		00				0		1562	Europe/Andorra	1993-12-23
+3039672	Borda de l’ Orri	Borda de l' Orri		42.55	1.43333	S	HUT	AD		00				0		1949	Europe/Andorra	1993-12-23
+3039673	Solana dels Oriols	Solana dels Oriols		42.56667	1.48333	T	SLP	AD		00				0		1508	Europe/Andorra	1993-12-23
+3039674	Cap dels Oriols	Cap dels Oriols		42.56667	1.46667	T	PK	AD		00				0		1673	Europe/Andorra	1993-12-23
+3039675	Pont d'Ordino	Pont d'Ordino		42.5492	1.52373	S	BDG	AD		07				0		1397	Europe/Andorra	2007-04-04
+3039676	Parròquia d'Ordino	Parroquia d'Ordino	Ordino,Parroquia d'Ordino,Parròquia d'Ordino	42.59758	1.52573	A	ADM1	AD		05				3467		1695	Europe/Andorra	2008-03-17
+3039677	Coll d'Ordino	Coll d'Ordino	Coll d'Ordino,Port d'Ordino	42.55615	1.57147	T	PASS	AD	AD	07				0	1883	1879	Europe/Andorra	2007-04-04
+3039678	Ordino	Ordino	Ordino,ao er di nuo,orudino jiao qu,Ордино,オルディノ教区,奥尔迪诺	42.55623	1.53319	P	PPLA	AD		05				3066		1340	Europe/Andorra	2009-12-11
+3039679	Font de les Ordigues	Font de les Ordigues		42.51667	1.56667	H	SPNG	AD		00				0		1759	Europe/Andorra	1993-12-23
+3039680	Font de l’ Ordigal	Font de l' Ordigal		42.46667	1.46667	H	SPNG	AD		00				0		1340	Europe/Andorra	1993-12-23
+3039681	Roc de l’ Oral	Roc de l' Oral		42.53333	1.56667	T	CLF	AD		00				0		1418	Europe/Andorra	1993-12-23
+3039682	Planells d’ Olio	Planells d' Olio		42.53333	1.6	T	UPLD	AD		00				0		1888	Europe/Andorra	1993-12-23
+3039683	Obagueta de Cantí	Obagueta de Canti		42.56667	1.51667	L	LCTY	AD		00				0		1500	Europe/Andorra	1993-12-23
+3039684	Riu de les Obagues	Riu de les Obagues		42.58333	1.63333	H	STM	AD		00				0		1722	Europe/Andorra	1993-12-23
+3039685	Canal de les Obagues	Canal de les Obagues		42.58333	1.48333	H	STM	AD		00				0		1809	Europe/Andorra	1993-12-23
+3039686	Bosc de les Obagues	Bosc de les Obagues		42.58333	1.63333	V	FRST	AD		00				0		1722	Europe/Andorra	1993-12-23
+3039687	Bosc de l’ Obaga Sobirana	Bosc de l' Obaga Sobirana		42.55	1.48333	V	FRST	AD		00				0		1548	Europe/Andorra	1993-12-23
+3039688	Canal de l’ Obaga Fosca	Canal de l' Obaga Fosca		42.48333	1.43333	H	STM	AD		00				0		1938	Europe/Andorra	1993-12-23
+3039689	Clots de l’ Obaga de Torradella	Clots de l' Obaga de Torradella		42.6	1.63333	H	RVN	AD		00				0		1893	Europe/Andorra	1993-12-23
+3039690	Serra de l’ Obaga d’Enclar	Serra de l' Obaga d'Enclar		42.51246	1.477	T	MT	AD		00				0		2069	Europe/Andorra	2011-04-19
+3039691	Obaga d’Enclar	Obaga d'Enclar		42.5	1.46667	A	ADMD	AD		00				0		1678	Europe/Andorra	1993-12-23
+3039692	Canal de l’ Obaga de l’Óssa	Canal de l' Obaga de l'Ossa		42.55	1.48333	H	STM	AD		00				0		1548	Europe/Andorra	1993-12-23
+3039693	Bosc de l’ Obaga de l’Óssa	Bosc de l' Obaga de l'Ossa		42.55	1.48333	V	FRST	AD		00				0		1548	Europe/Andorra	1993-12-23
+3039694	Obaga de l’Estall Serrer	Obaga de l'Estall Serrer		42.48333	1.6	A	ADMD	AD		00				0		2250	Europe/Andorra	1993-12-23
+3039695	Obaga de la Gonarda	Obaga de la Gonarda		42.55	1.53333	A	ADMD	AD		00				0		1593	Europe/Andorra	1993-12-23
+3039696	Obaga de Juclar	Obaga de Juclar		42.61667	1.7	L	LCTY	AD		00				0		2285	Europe/Andorra	1993-12-23
+3039697	Obaga de Juberri	Obaga de Juberri		42.43333	1.48333	A	ADMD	AD		00				0		1228	Europe/Andorra	1993-12-23
+3039698	Bosc de l’ Obaga de Gali	Bosc de l' Obaga de Gali		42.55	1.48333	V	FRST	AD		00				0		1548	Europe/Andorra	1993-12-23
+3039699	Obaga de Fontverd	Obaga de Fontverd		42.48333	1.58333	A	ADMD	AD		00				0		2349	Europe/Andorra	1993-12-23
+3039700	Obaga d’Ansalonga	Obaga d'Ansalonga		42.56667	1.51667	A	ADMD	AD		00				0		1500	Europe/Andorra	1993-12-23
+3039701	Obaga d’Andorra	Obaga d'Andorra		42.48333	1.51667	A	ADMD	AD		00				0		2061	Europe/Andorra	1993-12-23
+3039702	Camí de l’ Obaga	Cami de l' Obaga		42.55	1.55	R	TRL	AD		00				0		2097	Europe/Andorra	1993-12-23
+3039703	Serrat dels Obacs	Serrat dels Obacs		42.6	1.5	T	SLP	AD		00				0		1923	Europe/Andorra	1993-12-23
+3039704	Fonts dels Obacs	Fonts dels Obacs		42.6	1.5	H	SPNG	AD		00				0		1923	Europe/Andorra	1993-12-23
+3039705	Obac d’Incles	Obac d'Incles		42.58333	1.68333	A	ADMD	AD		00				0		2294	Europe/Andorra	1993-12-23
+3039706	Obac de Soldeu	Obac de Soldeu		42.56667	1.66667	A	ADMD	AD		00				0		1938	Europe/Andorra	1993-12-23
+3039707	Obac de Sispony	Obac de Sispony		42.51667	1.48333	A	ADMD	AD		00				0		1839	Europe/Andorra	1993-12-23
+3039708	Bosc de l’ Obac de Salla	Bosc de l' Obac de Salla		42.55	1.5	V	FRST	AD		00				0		1292	Europe/Andorra	1993-12-23
+3039709	Obac d’Envalira	Obac d'Envalira		42.55	1.68333	A	ADMD	AD		00				0		2254	Europe/Andorra	1993-12-23
+3039710	Obac d’Encamp	Obac d'Encamp		42.51667	1.6	A	ADMD	AD		00				0		2085	Europe/Andorra	1993-12-23
+3039711	Obac del Tarter	Obac del Tarter		42.56667	1.63333	A	ADMD	AD		00				0		2016	Europe/Andorra	1993-12-23
+3039712	Obac dels Cortals	Obac dels Cortals		42.51667	1.61667	A	ADMD	AD		00				0		2254	Europe/Andorra	1993-12-23
+3039713	Obac de les Escaldes i Engordany	Obac de les Escaldes i Engordany		42.5	1.53333	L	LCTY	AD		00				0		1574	Europe/Andorra	2007-04-05
+3039714	Obac de la Cebollera	Obac de la Cebollera		42.61667	1.58333	L	LCTY	AD		00				0		2374	Europe/Andorra	1993-12-23
+3039715	Pont de l’ Obac de Fontaneda	Pont de l' Obac de Fontaneda		42.45	1.46667	S	BDG	AD		00				0		935	Europe/Andorra	1993-12-23
+3039716	Obac de Canillo	Obac de Canillo		42.56667	1.63333	A	ADMD	AD		00				0		2016	Europe/Andorra	1993-12-23
+3039717	Obac d’Anyós	Obac d'Anyos		42.53333	1.53333	A	ADMD	AD		00				0		1521	Europe/Andorra	1993-12-23
+3039718	Serrat de l’ Obac	Serrat de l' Obac		42.48333	1.5	T	MT	AD		00				0		1631	Europe/Andorra	1993-12-23
+3039719	Rec de l’ Obac	Rec de l' Obac		42.5	1.53333	H	CNL	AD		00				0		1574	Europe/Andorra	1993-12-23
+3039720	Prats de l’ Obac	Prats de l' Obac		42.53333	1.61667	L	GRAZ	AD		00				0		2237	Europe/Andorra	1993-12-23
+3039721	Font de l’ Obac	Font de l' Obac		42.5	1.56667	H	SPNG	AD		00				0		1776	Europe/Andorra	1993-12-23
+3039722	Coll d’ Obac	Coll d' Obac		42.5	1.46667	T	PK	AD		00				0		1678	Europe/Andorra	1993-12-23
+3039723	Torrent dels Nyerros	Torrent dels Nyerros		42.48333	1.46667	H	STM	AD		00				0		1148	Europe/Andorra	1993-12-23
+3039724	Carretera General Número Un	Carretera General Numero Un		42.5	1.53333	R	RD	AD		00				0		1574	Europe/Andorra	1993-12-23
+3039725	Carretera General Número Tres	Carretera General Numero Tres		42.61667	1.48333	R	RD	AD		00				0		2470	Europe/Andorra	1993-12-23
+3039726	Carretera General Número Duo	Carretera General Numero Duo		42.53333	1.73333	R	RD	AD		00				0		2300	Europe/Andorra	1993-12-23
+3039727	Pleta Nova	Pleta Nova		42.61667	1.51667	L	GRAZ	AD		00				0		1716	Europe/Andorra	1993-12-23
+3039728	Obaga de Nou Fonts	Obaga de Nou Fonts		42.46667	1.53333	T	SLP	AD		00				0		2332	Europe/Andorra	1993-12-23
+3039729	Nou Fonts	Nou Fonts		42.46667	1.53333	T	RDGE	AD		00				0		2332	Europe/Andorra	1993-12-23
+3039730	Estany de la Nou	Estany de la Nou		42.47539	1.5756	H	LK	AD		00				0		2349	Europe/Andorra	2011-04-19
+3039731	Pic d’ Ascobes	Pic d' Ascobes	Pic d' Ascobes,Pic de Noe,Pic de Noé,Pic d’ Ascobes	42.61667	1.73333	T	PK	AD		00				0		2508	Europe/Andorra	2011-11-05
+3039732	Basera del Niu de l’Aliga	Basera del Niu de l'Aliga		42.5	1.45	T	CLF	AD		00				0		1840	Europe/Andorra	1993-12-23
+3039733	Collades de Nier	Collades de Nier		42.61667	1.53333	T	PASS	AD		00				0		1609	Europe/Andorra	1993-12-23
+3039734	Bosc de les Neres	Bosc de les Neres		42.53333	1.56667	V	FRST	AD		00				0		1418	Europe/Andorra	1993-12-23
+3039735	Bony de les Neres	Bony de les Neres	Bony de las Neras,Bony de les Neres,Bony de los Neros,Pic de las Neras	42.54761	1.56693	T	MT	AD		00				0		1828	Europe/Andorra	2011-11-05
+3039736	Roques Negres	Roques Negres		42.5	1.46667	T	RKS	AD		00				0		1678	Europe/Andorra	1993-12-23
+3039737	Rocs Negres	Rocs Negres		42.55	1.61667	T	RKS	AD		00				0		2206	Europe/Andorra	1993-12-23
+3039738	Canals Negres	Canals Negres		42.56667	1.68333	H	RVN	AD		00				0		2340	Europe/Andorra	1993-12-23
+3039739	Serrat Negre	Serrat Negre		42.58333	1.48333	T	SPUR	AD		00				0		1809	Europe/Andorra	1993-12-23
+3039740	Riu Negre	Riu Negre		42.45	1.48333	H	STM	AD		00				0		1111	Europe/Andorra	1993-12-23
+3039741	Port de Comallempla	Port de Comallempla	Port Negre,Port de Comallempla	42.56667	1.45	T	PASS	AD		00				0		2137	Europe/Andorra	2011-11-05
+3039742	Pic Negre	Pic Negre	Pic Negre	42.56667	1.45	T	PK	AD		00				0		2137	Europe/Andorra	2011-11-05
+3039743	Pic Negre	Pic Negre	Pic Negre	42.45	1.56667	T	PK	AD		00				0		2558	Europe/Andorra	2011-11-05
+3039744	Forat Negre	Forat Negre		42.5	1.5	H	RVN	AD		00				0		1135	Europe/Andorra	1993-12-23
+3039745	Estany Negre	Estany Negre		42.58333	1.43333	H	LK	AD		00				0		2412	Europe/Andorra	1993-12-23
+3039746	Bosc Negre	Bosc Negre		42.56667	1.55	V	FRST	AD		00				0		1996	Europe/Andorra	1993-12-23
+3039747	Bosc Negre	Bosc Negre		42.53333	1.6	V	FRST	AD		00				0		1888	Europe/Andorra	1993-12-23
+3039748	Bosc Negre	Bosc Negre		42.51667	1.48333	V	FRST	AD		00				0		1839	Europe/Andorra	1993-12-23
+3039749	Bosc Negre	Bosc Negre		42.5	1.56667	V	FRST	AD		00				0		1776	Europe/Andorra	1993-12-23
+3039750	Bosc Negre	Bosc Negre		42.48333	1.51667	V	FRST	AD		00				0		2061	Europe/Andorra	1993-12-23
+3039751	Bony Negre	Bony Negre		42.56667	1.46667	T	SPUR	AD		00				0		1673	Europe/Andorra	1993-12-23
+3039752	Roca Negra	Roca Negra		42.58333	1.58333	T	RK	AD		00				0		1993	Europe/Andorra	1993-12-23
+3039753	Torrent del Nedó	Torrent del Nedo		42.46667	1.5	H	STM	AD		00				0		1383	Europe/Andorra	1993-12-23
+3039754	Font de la Navina	Font de la Navina		42.55	1.56667	H	SPNG	AD		00				0		1828	Europe/Andorra	1993-12-23
+3039755	Llosers de Naudí	Llosers de Naudi		42.56667	1.56667	S	MNQR	AD		00				0		2089	Europe/Andorra	1993-12-23
+3039756	Carretera de Nagol	Carretera de Nagol		42.46667	1.48333	R	RD	AD		00				0		1134	Europe/Andorra	1993-12-23
+3039757	Nagol	Nagol	Nagol	42.47146	1.50314	P	PPL	AD		06				0		1383	Europe/Andorra	2011-11-05
+3039758	Solà de Nadal	Sola de Nadal		42.51667	1.51667	T	SLP	AD		00				0		1265	Europe/Andorra	1993-12-23
+3039759	Obaga de les Mussoles	Obaga de les Mussoles		42.55	1.63333	T	SLP	AD		00				0		2336	Europe/Andorra	1993-12-23
+3039760	Pla Mussola	Pla Mussola		42.53333	1.56667	T	UPLD	AD		00				0		1418	Europe/Andorra	1993-12-23
+3039761	Camí de la Muntanya	Cami de la Muntanya		42.5	1.56667	R	TRL	AD		00				0		1776	Europe/Andorra	1993-12-23
+3039762	Pleta de les Mules	Pleta de les Mules		42.43333	1.53333	L	GRAZ	AD		00				0		2108	Europe/Andorra	1993-12-23
+3039763	Canal del Mulassar	Canal del Mulassar		42.56667	1.51667	H	STM	AD		00				0		1500	Europe/Andorra	1993-12-23
+3039764	Bosc del Mulassar	Bosc del Mulassar		42.56667	1.53333	V	FRST	AD		00				0		1669	Europe/Andorra	1993-12-23
+3039765	Basers del Motxo	Basers del Motxo		42.6	1.63333	T	CLF	AD		00				0		1893	Europe/Andorra	1993-12-23
+3039766	Riu de Mossers	Riu de Mossers		42.45	1.46667	H	STM	AD		00				0		935	Europe/Andorra	1993-12-23
+3039767	Pleta Mosquera	Pleta Mosquera		42.63333	1.51667	L	GRAZ	AD		00				0		1894	Europe/Andorra	1993-12-23
+3039768	Mosquera	Mosquera		42.55	1.58333	P	PPL	AD		03				0		1499	Europe/Andorra	1993-12-23
+3039769	Tosa de Moscatosa	Tosa de Moscatosa		42.55	1.71667	T	UPLD	AD		00				0		2192	Europe/Andorra	1993-12-23
+3039770	Clots de Moscatosa	Clots de Moscatosa		42.55	1.7	H	RVN	AD		00				0		2358	Europe/Andorra	1993-12-23
+3039771	Pont de Mos	Pont de Mos		42.58333	1.63333	S	BDG	AD		00				0		1722	Europe/Andorra	1993-12-23
+3039772	Plana Mortalla	Plana Mortalla		42.58333	1.55	T	UPLD	AD		00				0		2357	Europe/Andorra	1993-12-23
+3039773	Estany Mort	Estany Mort		42.63333	1.61667	H	LK	AD		00				0		2541	Europe/Andorra	1993-12-23
+3039774	Estany Mort	Estany Mort		42.58333	1.71667	H	LK	AD		00				0		2553	Europe/Andorra	1993-12-23
+3039775	Canya dels Moros	Canya dels Moros		42.55	1.51667	S	CAVE	AD		00				0		1397	Europe/Andorra	1993-12-23
+3039776	Pleta de Moretó	Pleta de Moreto		42.55	1.68333	L	GRAZ	AD		00				0		2254	Europe/Andorra	1993-12-23
+3039777	Planell de Moretó	Planell de Moreto		42.55	1.68333	T	UPLD	AD		00				0		2254	Europe/Andorra	1993-12-23
+3039778	Bosc de Moretó	Bosc de Moreto		42.55	1.7	V	FRST	AD		00				0		2358	Europe/Andorra	1993-12-23
+3039779	Estany Moreno	Estany Moreno		42.51667	1.63333	H	LK	AD		00				0		2379	Europe/Andorra	1993-12-23
+3039780	Canal de Mora	Canal de Mora		42.56667	1.58333	H	STM	AD		00				0		1919	Europe/Andorra	1993-12-23
+3039781	Tosal de la Truita	Tosal de la Truita	Pic de Monturull,Pic de Perafita,Tosal de la Truita	42.46667	1.58333	T	PK	AD		00				0		2367	Europe/Andorra	2011-11-05
+3039782	Riu de Montuell	Riu de Montuell		42.51667	1.58333	H	STM	AD		00				0		1994	Europe/Andorra	1993-12-23
+3039783	Cap de Montuell	Cap de Montuell		42.51667	1.61667	T	PK	AD		00				0		2254	Europe/Andorra	1993-12-23
+3039784	Roc de Montmantell	Roc de Montmantell		42.59695	1.47085	T	RDGE	AD		00				0		2421	Europe/Andorra	2011-04-19
+3039785	Riu de Montmantell	Riu de Montmantell		42.6	1.46667	H	STM	AD		00				0		2421	Europe/Andorra	1993-12-23
+3039786	Pleta de Montmantell	Pleta de Montmantell		42.6	1.46667	L	GRAZ	AD		00				0		2421	Europe/Andorra	1993-12-23
+3039787	Obaga de Montmantell	Obaga de Montmantell		42.6	1.46667	T	SLP	AD		00				0		2421	Europe/Andorra	1993-12-23
+3039788	Font de Montmantell	Font de Montmantell		42.6	1.46667	H	SPNG	AD		00				0		2421	Europe/Andorra	1993-12-23
+3039789	Estanys de Montmantell	Estanys de Montmantell		42.6	1.46667	H	LKS	AD		00				0		2421	Europe/Andorra	1993-12-23
+3039790	Collada de Montmantell	Collada de Montmantell		42.6	1.46667	T	PASS	AD		00				0		2421	Europe/Andorra	1993-12-23
+3039791	Camí de Montmantell	Cami de Montmantell		42.6	1.46667	R	TRL	AD		00				0		2421	Europe/Andorra	1993-12-23
+3039792	Montmantell	Montmantell		42.6	1.46667	A	ADMD	AD		00				0		2421	Europe/Andorra	1993-12-23
+3039793	Pic de Montmalús	Pic de Montmalus		42.50902	1.6861	T	PK	AD		00				0		2445	Europe/Andorra	2011-04-19
+3039794	Estany de Montmalús	Estany de Montmalus		42.5	1.68333	H	LK	AD		00				0		2425	Europe/Andorra	1993-12-23
+3039795	Collada de Montmalús	Collada de Montmalus		42.51667	1.7	T	PASS	AD		00				0		2435	Europe/Andorra	1993-12-23
+3039796	Montmalús	Montmalus		42.5	1.7	A	ADMD	AD		00				0		2323	Europe/Andorra	1993-12-23
+3039797	Torrent de Montllobar	Torrent de Montllobar		42.45	1.51667	H	STM	AD		00				0		1790	Europe/Andorra	1993-12-23
+3039798	Font de Montllobar	Font de Montllobar		42.45	1.51667	H	SPNG	AD		00				0		1790	Europe/Andorra	1993-12-23
+3039799	Montllobar	Montllobar		42.45	1.51667	L	LCTY	AD		00				0		1790	Europe/Andorra	1993-12-23
+3039800	Riu de Montaup	Riu de Montaup		42.56667	1.6	H	STM	AD		00				0		1655	Europe/Andorra	1993-12-23
+3039801	Prats de Montaup	Prats de Montaup		42.56667	1.58333	L	GRAZ	AD		00				0		1919	Europe/Andorra	1993-12-23
+3039802	Collet de Montaup	Collet de Montaup		42.56667	1.58333	T	SPUR	AD		00				0		1919	Europe/Andorra	1993-12-23
+3039803	Carrera de Montaup	Carrera de Montaup		42.56667	1.6	R	RD	AD		00				0		1655	Europe/Andorra	1993-12-23
+3039804	Barranc de Montaup	Barranc de Montaup		42.56667	1.6	H	STM	AD		00				0		1655	Europe/Andorra	1993-12-23
+3039805	Montaup	Montaup		42.58333	1.58333	A	ADMD	AD		00				0		1993	Europe/Andorra	1993-12-23
+3039806	Riu Montaner	Riu Montaner		42.52965	1.52042	H	STM	AD		00				0		1361	Europe/Andorra	2011-04-19
+3039807	Collada de Montaner	Collada de Montaner	Col de Montaner,Col de Montanér,Coll de Montane,Coll de Montané,Collada de Montaner	42.51798	1.46716	T	PASS	AD		00				0		1840	Europe/Andorra	2011-11-05
+3039808	Riu de Montalarí	Riu de Montalari		42.53333	1.58333	H	STM	AD		00				0		1571	Europe/Andorra	1993-12-23
+3039809	Bordes de Montalarí	Bordes de Montalari		42.55	1.58333	S	HUTS	AD		00				0		1499	Europe/Andorra	1993-12-23
+3039810	Mónjol de Cabana Sorda	Monjol de Cabana Sorda		42.61667	1.68333	T	SLP	AD		00				0		2406	Europe/Andorra	1993-12-23
+3039811	Canal del Monjo	Canal del Monjo		42.48333	1.5	H	STM	AD		00				0		1631	Europe/Andorra	1993-12-23
+3039812	Tossal Momó	Tossal Momo		42.53333	1.46667	T	PK	AD		00				0		1846	Europe/Andorra	1993-12-23
+3039813	Pleta dels Moltons	Pleta dels Moltons		42.55	1.73333	L	GRAZ	AD		00				0		2100	Europe/Andorra	1993-12-23
+3039814	Obaga de la Mollerra	Obaga de la Mollerra		42.6	1.51667	T	SLP	AD		00				0		1445	Europe/Andorra	1993-12-23
+3039815	Pont de Molleres	Pont de Molleres		42.55	1.58333	S	BDG	AD		00				0		1499	Europe/Andorra	1993-12-23
+3039816	Canal de les Molleres	Canal de les Molleres		42.51667	1.56667	H	STM	AD		00				0		1759	Europe/Andorra	1993-12-23
+3039817	Canal de les Molleres	Canal de les Molleres		42.5	1.55	H	STM	AD		00				0		1566	Europe/Andorra	1993-12-23
+3039818	Bosc de les Molleres	Bosc de les Molleres		42.51667	1.56667	V	FRST	AD		00				0		1759	Europe/Andorra	1993-12-23
+3039819	Molleres	Molleres		42.55103	1.58958	P	PPL	AD		02				0		1640	Europe/Andorra	2011-04-19
+3039820	Molleres	Molleres		42.55	1.58333	L	LCTY	AD		00				0		1499	Europe/Andorra	1993-12-23
+3039821	Bosc de la Mollera	Bosc de la Mollera		42.6	1.51667	V	FRST	AD		00				0		1445	Europe/Andorra	1993-12-23
+3039822	Bordes de la Mollera	Bordes de la Mollera		42.6	1.51667	S	HUTS	AD		00				0		1445	Europe/Andorra	1993-12-23
+3039823	Torrent de la Molina	Torrent de la Molina		42.45	1.51667	H	STM	AD		00				0		1790	Europe/Andorra	1993-12-23
+3039824	Riu de la Molina	Riu de la Molina		42.53333	1.6	H	STM	AD		00				0		1888	Europe/Andorra	1993-12-23
+3039825	Obaga de la Molina	Obaga de la Molina		42.56667	1.48333	T	SLP	AD		00				0		1508	Europe/Andorra	1993-12-23
+3039826	Obaga de la Molina	Obaga de la Molina		42.45	1.51667	T	SLP	AD		00				0		1790	Europe/Andorra	1993-12-23
+3039827	Grau de la Molina	Grau de la Molina		42.53333	1.6	H	RVN	AD		00				0		1888	Europe/Andorra	1993-12-23
+3039828	Canal de la Molina	Canal de la Molina		42.48333	1.56667	H	STM	AD		00				0		2231	Europe/Andorra	1993-12-23
+3039829	Canal de la Molina	Canal de la Molina		42.48333	1.46667	H	STM	AD		00				0		1148	Europe/Andorra	1993-12-23
+3039830	Camí de la Molina	Cami de la Molina		42.53333	1.6	R	TRL	AD		00				0		1888	Europe/Andorra	1993-12-23
+3039831	Bordes de la Molina	Bordes de la Molina		42.51667	1.58333	S	HUT	AD		00				0		1994	Europe/Andorra	1993-12-23
+3039832	Plana Moleta	Plana Moleta		42.56667	1.53333	T	UPLD	AD		00				0		1669	Europe/Andorra	1993-12-23
+3039833	Roc de les Moles	Roc de les Moles		42.53333	1.51667	T	RK	AD		00				0		1361	Europe/Andorra	1993-12-23
+3039834	Pont de les Moles	Pont de les Moles		42.6	1.53333	S	BDG	AD		00				0		1695	Europe/Andorra	1993-12-23
+3039835	Canal de les Moles	Canal de les Moles		42.56667	1.61667	H	RVN	AD		00				0		1920	Europe/Andorra	1993-12-23
+3039836	Pont de la Mola	Pont de la Mola		42.56667	1.66667	S	BDG	AD		00				0		1938	Europe/Andorra	1993-12-23
+3039837	Roc del Moixó	Roc del Moixo		42.56667	1.5	T	RK	AD		00				0		1636	Europe/Andorra	1993-12-23
+3039838	Borda del Moixellaire	Borda del Moixellaire		42.45	1.45	S	HUTS	AD		00				0		1482	Europe/Andorra	1993-12-23
+3039839	Torrent de la Moixella	Torrent de la Moixella		42.43333	1.48333	H	STM	AD		00				0		1228	Europe/Andorra	1993-12-23
+3039840	Riu de la Moixella	Riu de la Moixella		42.45	1.48333	H	STM	AD		00				0		1111	Europe/Andorra	1993-12-23
+3039841	Bosc de la Moixella	Bosc de la Moixella		42.45	1.46667	V	FRST	AD		00				0		935	Europe/Andorra	1993-12-23
+3039842	Serra Mitjana	Serra Mitjana		42.46667	1.61667	T	RDGE	AD		00				0		2448	Europe/Andorra	1993-12-23
+3039843	Serra Mitjana	Serra Mitjana		42.46667	1.58333	T	MT	AD		00				0		2367	Europe/Andorra	1993-12-23
+3039844	Bony de Mitgeu	Bony de Mitgeu		42.55	1.53333	T	SPUR	AD		00				0		1593	Europe/Andorra	1993-12-23
+3039845	Collet de la Mira	Collet de la Mira		42.56667	1.53333	T	SPUR	AD		00				0		1669	Europe/Andorra	1993-12-23
+3039846	Serrat dels Miquelets	Serrat dels Miquelets		42.55	1.6	T	RDGE	AD		00				0		2210	Europe/Andorra	1993-12-23
+3039847	Font dels Miquelets	Font dels Miquelets		42.58333	1.43333	H	SPNG	AD		00				0		2412	Europe/Andorra	1993-12-23
+3039848	Pont de les Mines	Pont de les Mines		42.6	1.53333	S	BDG	AD		00				0		1695	Europe/Andorra	1993-12-23
+3039849	Tosa del Mig	Tosa del Mig		42.58333	1.7	T	UPLD	AD		00				0		2584	Europe/Andorra	1993-12-23
+3039850	Serra del Mig	Serra del Mig		42.58333	1.71667	T	RDGE	AD		00				0		2553	Europe/Andorra	1993-12-23
+3039851	Roc del Mig	Roc del Mig		42.56667	1.71667	T	RK	AD		00				0		2219	Europe/Andorra	1993-12-23
+3039852	Estany del Mig	Estany del Mig		42.63999	1.48612	H	LK	AD		07				0		2254	Europe/Andorra	2007-03-04
+3039853	Coma del Mig	Coma del Mig		42.65	1.53333	T	CRQ	AD		00				0		2564	Europe/Andorra	1993-12-23
+3039854	Collada del Mig	Collada del Mig		42.61667	1.55	T	SPUR	AD		00				0		2007	Europe/Andorra	1993-12-23
+3039855	Clots del Mig	Clots del Mig		42.56667	1.55	H	RVN	AD		00				0		1996	Europe/Andorra	1993-12-23
+3039856	Carrera del Mig	Carrera del Mig		42.56667	1.61667	R	TRL	AD		00				0		1920	Europe/Andorra	1993-12-23
+3039857	Basers del Mig	Basers del Mig		42.58333	1.7	T	CLF	AD		00				0		2584	Europe/Andorra	1993-12-23
+3039858	Clots de Més Amunt de la Pleta	Clots de Mes Amunt de la Pleta		42.6	1.48333	T	TAL	AD		00				0		2441	Europe/Andorra	1993-12-23
+3039859	Pleta de Més Amunt	Pleta de Mes Amunt		42.51667	1.63333	L	GRAZ	AD		00				0		2379	Europe/Andorra	1993-12-23
+3039860	Estany de Més Amunt	Estany de Mes Amunt		42.6457	1.48659	H	LK	AD		07				0		2530	Europe/Andorra	2007-03-04
+3039861	Carretera Meritxell	Carretera Meritxell		42.55	1.58333	R	RD	AD		00				0		1499	Europe/Andorra	1993-12-23
+3039862	Meritxell	Meritxell	Sanctuaire de Meritxeli,Sanctuaire de Meritxell,Santuari de Meritxell	42.55403	1.59087	P	PPL	AD	AD	02				0		1640	Europe/Andorra	2007-04-16
+3039863	Rec de Mereig	Rec de Mereig		42.56667	1.58333	H	CNL	AD		00				0		1919	Europe/Andorra	1993-12-23
+3039864	Pont de Mereig	Pont de Mereig		42.55	1.6	S	BDG	AD		00				0		2210	Europe/Andorra	1993-12-23
+3039865	Planells de Mereig	Planells de Mereig		42.56667	1.58333	T	UPLD	AD		00				0		1919	Europe/Andorra	1993-12-23
+3039866	Bosc de Mereig	Bosc de Mereig		42.56667	1.58333	V	FRST	AD		00				0		1919	Europe/Andorra	1993-12-23
+3039867	Bordes de Mereig	Bordes de Mereig		42.56302	1.58293	S	FRMS	AD		00				0		1637	Europe/Andorra	2011-04-19
+3039868	Mereig	Mereig		42.56667	1.58333	A	ADMD	AD		00				0		1919	Europe/Andorra	1993-12-23
+3039869	Font de la Mentirosa	Font de la Mentirosa		42.43333	1.51667	H	SPNG	AD		00				0		2031	Europe/Andorra	1993-12-23
+3039870	Estany dels Meners de la Coma	Estany dels Meners de la Coma		42.61667	1.61667	H	LK	AD		00				0		2352	Europe/Andorra	1993-12-23
+3039871	Riu dels Meners	Riu dels Meners		42.61667	1.63333	H	STM	AD		00				0		2331	Europe/Andorra	1993-12-23
+3039872	Font dels Meners	Font dels Meners		42.61667	1.6	H	SPNG	AD		00				0		2528	Europe/Andorra	1993-12-23
+3039873	Font dels Meners	Font dels Meners		42.46667	1.48333	H	SPNG	AD		00				0		1134	Europe/Andorra	1993-12-23
+3039874	Collada dels Meners	Collada dels Meners		42.61667	1.6	T	PASS	AD		00				0		2528	Europe/Andorra	1993-12-23
+3039875	Pic de la Menera	Pic de la Menera		42.51667	1.71667	T	PK	AD		00				0		2591	Europe/Andorra	1993-12-23
+3039876	Clots de la Menera	Clots de la Menera		42.51667	1.71667	H	RVN	AD		00				0		2591	Europe/Andorra	1993-12-23
+3039877	Bosc del Menadís	Bosc del Menadis		42.45	1.46667	V	FRST	AD		00				0		935	Europe/Andorra	1993-12-23
+3039878	Meligar d’Emportona	Meligar d'Emportona		42.53333	1.66667	L	LCTY	AD		00				0		2489	Europe/Andorra	1993-12-23
+3039879	Serrat de Meligar	Serrat de Meligar		42.55	1.45	T	RDGE	AD		00				0		1788	Europe/Andorra	1993-12-23
+3039880	Estany del Meligar	Estany del Meligar		42.51667	1.66667	H	LK	AD		00				0		2410	Europe/Andorra	1993-12-23
+3039881	Roc del Melic	Roc del Melic		42.58333	1.58333	T	RK	AD		00				0		1993	Europe/Andorra	1993-12-23
+3039882	Pic de Medécourbe	Pic de Medecourbe	Pic de Madecourbe,Pic de Medecorba,Pic de Medecourbe,Pic de Medécourbe	42.6037	1.44264	T	PK	AD		00				0	2914	2658	Europe/Andorra	2011-02-09
+3039883	Camí dels Matxos	Cami dels Matxos		42.5	1.56667	R	TRL	AD		00				0		1776	Europe/Andorra	1993-12-23
+3039884	Basera Mateu	Basera Mateu		42.5	1.5	T	CLF	AD		00				0		1135	Europe/Andorra	1993-12-23
+3039885	Serrat dels Matets	Serrat dels Matets		42.56667	1.5	T	SPUR	AD		00				0		1636	Europe/Andorra	1993-12-23
+3039886	Bosc del Matet	Bosc del Matet		42.61667	1.53333	V	FRST	AD		00				0		1609	Europe/Andorra	1993-12-23
+3039887	Bosc de les Matelles	Bosc de les Matelles		42.51667	1.48333	V	FRST	AD		00				0		1839	Europe/Andorra	1993-12-23
+3039888	Clot de la Mata	Clot de la Mata		42.56667	1.68333	T	SLP	AD		00				0		2340	Europe/Andorra	1993-12-23
+3039889	Canals de la Mata	Canals de la Mata		42.61667	1.58333	H	RVN	AD		00				0		2374	Europe/Andorra	1993-12-23
+3039890	Canal de la Mata	Canal de la Mata		42.51667	1.51667	H	STM	AD		00				0		1265	Europe/Andorra	1993-12-23
+3039891	Bosc de la Mata	Bosc de la Mata		42.6	1.68333	V	FRST	AD		00				0		2089	Europe/Andorra	1993-12-23
+3039892	Bosc de la Mata	Bosc de la Mata		42.6	1.61667	V	FRST	AD		00				0		2271	Europe/Andorra	1993-12-23
+3039893	Massolina	Massolina		42.5	1.61667	H	RVN	AD		00				0		2560	Europe/Andorra	1993-12-23
+3039894	Riu de Massat	Riu de Massat		42.556	1.68641	H	STM	AD		00				0		2083	Europe/Andorra	2011-04-19
+3039895	Cortal del Masover	Cortal del Masover		42.53333	1.53333	S	CRRL	AD		00				0		1521	Europe/Andorra	1993-12-23
+3039896	Mas de Ribafeta	Mas de Ribafeta		42.56936	1.48837	P	PPL	AD		04				0		1655	Europe/Andorra	2011-04-19
+3039897	Pont del Mas d’En Soler	Pont del Mas d'En Soler		42.56667	1.51667	S	BDG	AD		00				0		1500	Europe/Andorra	1993-12-23
+3039898	Devesa del Mas d’Alins	Devesa del Mas d'Alins		42.45	1.45	L	GRAZ	AD		00				0		1482	Europe/Andorra	1993-12-23
+3039899	Carretera del Mas d’Alins	Carretera del Mas d'Alins		42.45	1.46667	R	RD	AD		00				0		935	Europe/Andorra	1993-12-23
+3039900	Borda del Mas d’Alins	Borda del Mas d'Alins		42.43333	1.45	S	HUTS	AD		00				0		877	Europe/Andorra	1993-12-23
+3039901	Mas d’Alins	Mas d'Alins		42.44126	1.44944	P	PPL	AD		06				0		1197	Europe/Andorra	2011-04-19
+3039902	Mas d’Alins	Mas d'Alins		42.45	1.45	A	ADMD	AD		00				0		1482	Europe/Andorra	1993-12-23
+3039903	Solà del Mas	Sola del Mas		42.45	1.5	T	SLP	AD		00				0		1614	Europe/Andorra	1993-12-23
+3039904	Obac del Mas	Obac del Mas		42.56667	1.5	T	SLP	AD		00				0		1636	Europe/Andorra	1993-12-23
+3039905	Camí del Mas	Cami del Mas		42.45	1.5	R	TRL	AD		00				0		1614	Europe/Andorra	1993-12-23
+3039906	Bordes del Mas	Bordes del Mas		42.45	1.5	S	HUTS	AD		00				0		1614	Europe/Andorra	1993-12-23
+3039907	Allau del Mas	Allau del Mas		42.56667	1.48333	H	STM	AD		00				0		1508	Europe/Andorra	1993-12-23
+3039908	Borda del Marticella	Borda del Marticella		42.58333	1.65	S	HUT	AD		00				0		1767	Europe/Andorra	1993-12-23
+3039909	Cortal del Martí	Cortal del Marti		42.53333	1.53333	S	CRRL	AD		00				0		1521	Europe/Andorra	1993-12-23
+3039910	Collet Martí	Collet Marti		42.5	1.48333	T	SPUR	AD		00				0		1316	Europe/Andorra	1993-12-23
+3039911	Collet Martí	Collet Marti		42.46667	1.46667	T	PK	AD		00				0		1340	Europe/Andorra	1993-12-23
+3039912	Borda del Martí	Borda del Marti		42.56667	1.6	S	HUT	AD		00				0		1655	Europe/Andorra	1993-12-23
+3039913	Marrades Negres	Marrades Negres		42.56667	1.7	T	TAL	AD		00				0		2375	Europe/Andorra	1993-12-23
+3039914	Marrades Negres	Marrades Negres		42.56667	1.55	H	STM	AD		00				0		1996	Europe/Andorra	1993-12-23
+3039915	Camí de les Marrades	Cami de les Marrades		42.55	1.5	R	TRL	AD		00				0		1292	Europe/Andorra	1993-12-23
+3039916	Bony de les Marrades	Bony de les Marrades		42.53333	1.5	T	PK	AD		00				0		1357	Europe/Andorra	1993-12-23
+3039917	Roc de Maria	Roc de Maria		42.5	1.48333	T	RK	AD		00				0		1316	Europe/Andorra	1993-12-23
+3039918	Canal de Maria	Canal de Maria		42.56667	1.48333	H	STM	AD		00				0		1508	Europe/Andorra	1993-12-23
+3039919	Pont de la Margineda	Pont de la Margineda		42.4838	1.49042	S	BDG	AD		00				0		991	Europe/Andorra	2011-04-19
+3039920	Coll de la Manyiga	Coll de la Manyiga		42.46667	1.53333	T	SPUR	AD		00				0		2332	Europe/Andorra	1993-12-23
+3039921	Coll de la Manyiga	Coll de la Manyiga		42.46667	1.48333	T	PASS	AD		00				0		1134	Europe/Andorra	1993-12-23
+3039922	Cortals de Manyat	Cortals de Manyat		42.48333	1.51667	S	HUTS	AD		00				0		2061	Europe/Andorra	1993-12-23
+3039923	Manyat	Manyat		42.47591	1.51661	L	LCTY	AD		00				0		1892	Europe/Andorra	2011-04-19
+3039924	Riu del Manegor	Riu del Manegor		42.6	1.68333	H	STM	AD		00				0		2089	Europe/Andorra	1993-12-23
+3039925	Pleta del Manegor	Pleta del Manegor		42.61667	1.7	L	GRAZ	AD		00				0		2285	Europe/Andorra	1993-12-23
+3039926	Bosc de la Mandurana	Bosc de la Mandurana		42.56667	1.61667	V	FRST	AD		00				0		1920	Europe/Andorra	1993-12-23
+3039927	Borda del Mandicó	Borda del Mandico		42.51667	1.55	S	HUT	AD		00				0		1322	Europe/Andorra	1993-12-23
+3039928	Pont del Mamó	Pont del Mamo		42.55	1.48333	S	BDG	AD		00				0		1548	Europe/Andorra	1993-12-23
+3039929	Font de Mallol	Font de Mallol		42.55	1.55	H	SPNG	AD		00				0		2097	Europe/Andorra	1993-12-23
+3039930	Canals Males	Canals Males		42.46667	1.48333	H	STM	AD		00				0		1134	Europe/Andorra	1993-12-23
+3039931	Canals Males	Canals Males		42.58333	1.46667	H	RVN	AD		00				0		1643	Europe/Andorra	1993-12-23
+3039932	Canal Mala	Canal Mala		42.45	1.5	H	RVN	AD		00				0		1614	Europe/Andorra	1993-12-23
+3039933	Roca Major	Roca Major		42.43333	1.5	T	PK	AD		00				0		1804	Europe/Andorra	1993-12-23
+3039934	Clot dels Mais	Clot dels Mais		42.56667	1.61667	H	RVN	AD		00				0		1920	Europe/Andorra	1993-12-23
+3039935	Planada dels Maians	Planada dels Maians		42.55	1.61667	T	UPLD	AD		00				0		2206	Europe/Andorra	1993-12-23
+3039936	Pic dels Maians	Pic dels Maians		42.55	1.61667	T	PK	AD		00				0		2206	Europe/Andorra	1993-12-23
+3039937	Costa dels Maians	Costa dels Maians		42.55	1.61667	T	SLP	AD		00				0		2206	Europe/Andorra	1993-12-23
+3039938	Canal dels Maians	Canal dels Maians		42.5	1.51667	H	STM	AD		00				0		1410	Europe/Andorra	1993-12-23
+3039939	Bosc dels Maians	Bosc dels Maians		42.48333	1.51667	V	FRST	AD		00				0		2061	Europe/Andorra	1993-12-23
+3039940	Bony dels Maians	Bony dels Maians		42.53333	1.61667	T	SPUR	AD		00				0		2237	Europe/Andorra	1993-12-23
+3039941	Pic de la Maiana	Pic de la Maiana		42.4821	1.60014	T	PK	AD		00				0		2250	Europe/Andorra	2011-04-19
+3039942	Collada de la Maiana	Collada de la Maiana		42.48333	1.6	T	PASS	AD		00				0		2250	Europe/Andorra	1993-12-23
+3039943	Tosa del Maià	Tosa del Maia		42.55	1.71667	T	UPLD	AD		00				0		2192	Europe/Andorra	1993-12-23
+3039944	Pleta del Maià	Pleta del Maia		42.56667	1.73333	L	GRAZ	AD		00				0		2096	Europe/Andorra	1993-12-23
+3039945	Pic del Maià	Pic del Maia	Pic Mata,Pic del Maia,Pic del Maià	42.55	1.71667	T	PK	AD	AD	00				0		2192	Europe/Andorra	2011-11-05
+3039946	Obagot del Maià	Obagot del Maia		42.56667	1.73333	T	SLP	AD		00				0		2096	Europe/Andorra	1993-12-23
+3039947	Riu Madriu	Riu Madriu	Madriu,Riu Madriu	42.49697	1.57954	H	STM	AD		00				0		1888	Europe/Andorra	2011-11-05
+3039948	Basers de Madona	Basers de Madona		42.61667	1.63333	T	CLF	AD		00				0		2331	Europe/Andorra	1993-12-23
+3039949	Canal de Luixent Passader	Canal de Luixent Passader		42.5	1.5	H	STM	AD		00				0		1135	Europe/Andorra	1993-12-23
+3039950	L’Ovella	L'Ovella		42.56667	1.6	L	LCTY	AD		00				0		1655	Europe/Andorra	1993-12-23
+3039951	Los Travessers	Los Travessers		42.56667	1.43333	L	LCTY	AD		00				0		2402	Europe/Andorra	1993-12-23
+3039952	L’Orri Amagat	L'Orri Amagat		42.6	1.6	L	LCTY	AD		00				0		2143	Europe/Andorra	1993-12-23
+3039953	L’Obagueta	L'Obagueta		42.53333	1.55	L	LCTY	AD		00				0		1344	Europe/Andorra	1993-12-23
+3039954	Roc dels Llumeners	Roc dels Llumeners		42.58333	1.46667	T	RK	AD		00				0		1643	Europe/Andorra	1993-12-23
+3039955	Canal dels Llumeners	Canal dels Llumeners		42.58333	1.46667	H	RVN	AD		00				0		1643	Europe/Andorra	1993-12-23
+3039956	Riu de Llumeneres	Riu de Llumeneres		42.46591	1.49579	H	STM	AD		00				0		1232	Europe/Andorra	2011-04-19
+3039957	Plana de Llumeneres	Plana de Llumeneres		42.46667	1.51667	T	UPLD	AD		00				0		1985	Europe/Andorra	1993-12-23
+3039958	Cortal de Llumeneres	Cortal de Llumeneres		42.46667	1.5	S	CRRL	AD		00				0		1383	Europe/Andorra	1993-12-23
+3039959	Llumeneres	Llumeneres	Llumeneres	42.46667	1.51667	P	PPL	AD		06				0		1985	Europe/Andorra	2011-11-05
+3039960	Canals del Lloset	Canals del Lloset		42.53333	1.58333	H	STM	AD		00				0		1571	Europe/Andorra	1993-12-23
+3039961	Canal del Lloset	Canal del Lloset		42.55	1.5	H	STM	AD		00				0		1292	Europe/Andorra	1993-12-23
+3039962	Bordes del Lloset	Bordes del Lloset		42.55	1.6	S	HUT	AD		00				0		2210	Europe/Andorra	1993-12-23
+3039963	Lloset	Lloset		42.53333	1.6	A	ADMD	AD		00				0		1888	Europe/Andorra	1993-12-23
+3039964	Costa del Lloser de Naudí	Costa del Lloser de Naudi		42.56667	1.56667	T	SLP	AD		00				0		2089	Europe/Andorra	1993-12-23
+3039965	Solana del Lloser	Solana del Lloser		42.46667	1.45	T	SLP	AD		00				0		1562	Europe/Andorra	1993-12-23
+3039966	Roc del Lloser	Roc del Lloser		42.58333	1.51667	T	RK	AD		00				0		1722	Europe/Andorra	1993-12-23
+3039967	Canal del Lloser	Canal del Lloser		42.51667	1.51667	H	STM	AD		00				0		1265	Europe/Andorra	1993-12-23
+3039968	Tossal de la Llosada	Tossal de la Llosada	Pic Llosada,Tossal de la Llosada	42.54862	1.64567	T	PK	AD		00				0		2422	Europe/Andorra	2011-11-05
+3039969	Tosa de la Llosada	Tosa de la Llosada		42.55	1.63333	T	UPLD	AD		00				0		2336	Europe/Andorra	1993-12-23
+3039970	Riu de la Llosada	Riu de la Llosada		42.53333	1.6	H	STM	AD		00				0		1888	Europe/Andorra	1993-12-23
+3039971	Obaga de la Llosada	Obaga de la Llosada		42.53333	1.61667	T	SLP	AD		00				0		2237	Europe/Andorra	1993-12-23
+3039972	Emprius de la Llosada	Emprius de la Llosada		42.53333	1.61667	L	CMN	AD		00				0		2237	Europe/Andorra	1993-12-23
+3039973	Basers de la Llosada	Basers de la Llosada		42.55	1.63333	T	CLF	AD		00				0		2336	Europe/Andorra	1993-12-23
+3039974	Riu Llosà	Riu Llosa		42.45	1.46667	H	STM	AD		00				0		935	Europe/Andorra	1993-12-23
+3039975	Grau de la Llosa	Grau de la Llosa		42.61667	1.55	T	SLP	AD		00				0		2007	Europe/Andorra	1993-12-23
+3039976	Collet de la Llosa	Collet de la Llosa		42.56667	1.5	T	PASS	AD		00				0		1636	Europe/Andorra	1993-12-23
+3039977	Clots de la Llosa	Clots de la Llosa		42.61667	1.61667	H	RVN	AD		00				0		2352	Europe/Andorra	1993-12-23
+3039978	Canal de la Llosa	Canal de la Llosa		42.56667	1.5	H	STM	AD		00				0		1636	Europe/Andorra	1993-12-23
+3039979	Llorts	Llorts	Llors,Llorta,Lors	42.59625	1.52658	P	PPL	AD	AD	05				0		1695	Europe/Andorra	2007-04-16
+3039980	Canal de les Llongues	Canal de les Llongues		42.55	1.51667	H	STM	AD		00				0		1397	Europe/Andorra	1993-12-23
+3039981	Bosc de les Llongues	Bosc de les Llongues		42.55	1.51667	V	FRST	AD		00				0		1397	Europe/Andorra	1993-12-23
+3039982	Costa dels Llomassos	Costa dels Llomassos		42.58333	1.45	T	SLP	AD		00				0		2156	Europe/Andorra	1993-12-23
+3039983	Canal dels Llomassos	Canal dels Llomassos		42.55	1.46667	H	STM	AD		00				0		1585	Europe/Andorra	1993-12-23
+3039984	Pleta del Llomar	Pleta del Llomar		42.61667	1.56667	L	GRAZ	AD		00				0		2228	Europe/Andorra	1993-12-23
+3039985	Clot del Llomar	Clot del Llomar		42.53333	1.48333	H	RVN	AD		00				0		1677	Europe/Andorra	1993-12-23
+3039986	Camí de la Llobatera	Cami de la Llobatera		42.55	1.48333	R	TRL	AD		00				0		1548	Europe/Andorra	1993-12-23
+3039987	Canal Llisa	Canal Llisa		42.56667	1.51667	H	STM	AD		00				0		1500	Europe/Andorra	1993-12-23
+3039988	Canal Llisa	Canal Llisa		42.53333	1.6	H	STM	AD		00				0		1888	Europe/Andorra	1993-12-23
+3039989	Torrent Llimois	Torrent Llimois		42.48333	1.43333	H	STM	AD		00				0		1938	Europe/Andorra	1993-12-23
+3039990	Solana dels Llimois	Solana dels Llimois		42.5	1.43333	T	SLP	AD		00				0		1654	Europe/Andorra	1993-12-23
+3039991	Bosc de Llevai	Bosc de Llevai		42.53333	1.55	V	FRST	AD		00				0		1344	Europe/Andorra	1993-12-23
+3039992	Basers de la Llessa	Basers de la Llessa		42.48333	1.5	T	CLF	AD		00				0		1631	Europe/Andorra	1993-12-23
+3039993	Planell de la Llentiga	Planell de la Llentiga		42.6	1.51667	T	UPLD	AD		00				0		1445	Europe/Andorra	1993-12-23
+3039994	Barranc del Llempo	Barranc del Llempo		42.55	1.51667	H	STM	AD		00				0		1397	Europe/Andorra	1993-12-23
+3039995	Casa Llècsia	Casa Llecsia		42.56667	1.6	S	HSE	AD		00				0		1655	Europe/Andorra	1993-12-23
+3039996	Borda del Llècsia	Borda del Llecsia		42.58333	1.6	S	HUT	AD		00				0		1828	Europe/Andorra	1993-12-23
+3039997	Solana dels Llaurers	Solana dels Llaurers		42.48333	1.43333	T	SLP	AD		00				0		1938	Europe/Andorra	1993-12-23
+3039998	Obaga dels Llaurers	Obaga dels Llaurers		42.48333	1.43333	T	SLP	AD		00				0		1938	Europe/Andorra	1993-12-23
+3039999	Bony dels Llaurers	Bony dels Llaurers		42.48333	1.43333	T	PK	AD		00				0		1938	Europe/Andorra	1993-12-23
+3040000	Roc Llarg	Roc Llarg		42.55	1.45	T	SPUR	AD		00				0		1788	Europe/Andorra	1993-12-23
+3040001	Pont del Llarg	Pont del Llarg		42.6	1.68333	S	BDG	AD		00				0		2089	Europe/Andorra	1993-12-23
+3040002	Fontanal Llarg	Fontanal Llarg		42.53333	1.46667	H	SPNG	AD		00				0		1846	Europe/Andorra	1993-12-23
+3040003	Casa Llarg	Casa Llarg		42.55	1.58333	S	HSE	AD		00				0		1499	Europe/Andorra	1993-12-23
+3040004	Canal del Llarg	Canal del Llarg		42.5	1.48333	H	STM	AD		00				0		1316	Europe/Andorra	1993-12-23
+3040005	Solana dels Llampells	Solana dels Llampells		42.51667	1.46667	T	SLP	AD		00				0		1840	Europe/Andorra	1993-12-23
+3040006	Torrent de la Llampa	Torrent de la Llampa		42.56667	1.6	H	STM	AD		00				0		1655	Europe/Andorra	1993-12-23
+3040007	Riu dels Llacs	Riu dels Llacs		42.55	1.43333	H	STM	AD		00				0		1949	Europe/Andorra	1993-12-23
+3040008	Pleta dels Llacs	Pleta dels Llacs		42.6	1.63333	L	GRAZ	AD		00				0		1893	Europe/Andorra	1993-12-23
+3040009	Pic dels Llacs	Pic dels Llacs	Pic dels Llacs	42.53333	1.41667	T	PK	AD		00				0		1948	Europe/Andorra	2011-11-05
+3040010	Pales dels Llacs	Pales dels Llacs		42.6	1.61667	T	CLF	AD		00				0		2271	Europe/Andorra	1993-12-23
+3040011	Font dels Llacs	Font dels Llacs		42.55	1.43333	H	SPNG	AD		00				0		1949	Europe/Andorra	1993-12-23
+3040012	Bosc dels Llacs	Bosc dels Llacs		42.55	1.41667	V	FRST	AD		00				0		2105	Europe/Andorra	1993-12-23
+3040013	L’Hospital	L'Hospital		42.48333	1.55	A	ADMD	AD		00				0		2233	Europe/Andorra	1993-12-23
+3040014	L’Hortó	L'Horto		42.58333	1.63333	L	LCTY	AD		00				0		1722	Europe/Andorra	1993-12-23
+3040015	L’Hortó	L'Horto		42.56667	1.51667	L	LCTY	AD		00				0		1500	Europe/Andorra	1993-12-23
+3040016	L’Hortell	L'Hortell		42.61667	1.51667	L	LCTY	AD		00				0		1716	Europe/Andorra	1993-12-23
+3040017	Les Tres Oles	Les Tres Oles		42.51667	1.55	H	RVN	AD		00				0		1322	Europe/Andorra	1993-12-23
+3040018	Les Tres Fonts	Les Tres Fonts		42.5	1.46667	H	SPNG	AD		00				0		1678	Europe/Andorra	1993-12-23
+3040019	Les Tarteres	Les Tarteres		42.45	1.48333	L	LCTY	AD		00				0		1111	Europe/Andorra	1993-12-23
+3040020	L’Estanyassa	L'Estanyassa		42.58333	1.65	L	LCTY	AD		00				0		1767	Europe/Andorra	1993-12-23
+3040021	Les Tallades	Les Tallades		42.61667	1.55	A	ADMD	AD		00				0		2007	Europe/Andorra	1993-12-23
+3040022	L’Estall	L'Estall		42.5	1.58333	L	LCTY	AD		00				0		1888	Europe/Andorra	1993-12-23
+3040023	Les Sorobilles	Les Sorobilles		42.56667	1.53333	T	CLF	AD		00				0		1669	Europe/Andorra	1993-12-23
+3040024	Les Solanelles	Les Solanelles		42.55	1.6	L	LCTY	AD		00				0		2210	Europe/Andorra	1993-12-23
+3040025	Les Sobiranes	Les Sobiranes		42.61667	1.55	L	LCTY	AD		00				0		2007	Europe/Andorra	1993-12-23
+3040026	Les Salses	Les Salses		42.63333	1.5	T	SLP	AD		00				0		1979	Europe/Andorra	1993-12-23
+3040027	Les Salines	Les Salines		42.60952	1.53697	P	PPL	AD		05				0		1793	Europe/Andorra	2007-04-16
+3040028	Les Ribaltes	Les Ribaltes		42.53333	1.53333	L	LCTY	AD		00				0		1521	Europe/Andorra	1993-12-23
+3040029	Les Rebes	Les Rebes		42.61667	1.61667	T	UPLD	AD		00				0		2352	Europe/Andorra	1993-12-23
+3040030	Les Queroles	Les Queroles		42.6	1.53333	L	LCTY	AD		00				0		1695	Europe/Andorra	1993-12-23
+3040031	Les Portes	Les Portes		42.48333	1.48333	L	LCTY	AD		00				0		981	Europe/Andorra	1993-12-23
+3040032	Les Planes de Sornàs	Les Planes de Sornas		42.56667	1.53333	L	LCTY	AD		00				0		1669	Europe/Andorra	1993-12-23
+3040033	Les Planes	Les Planes		42.63333	1.5	L	LCTY	AD		00				0		1979	Europe/Andorra	1993-12-23
+3040034	Les Planes	Les Planes		42.53333	1.6	A	ADMD	AD		00				0		1888	Europe/Andorra	1993-12-23
+3040035	Les Planades	Les Planades		42.6	1.68333	L	LCTY	AD		00				0		2089	Europe/Andorra	1993-12-23
+3040036	Les Pedrusques	Les Pedrusques		42.51667	1.63333	T	SLP	AD		00				0		2379	Europe/Andorra	1993-12-23
+3040037	Les Pedrasses	Les Pedrasses		42.55	1.51667	L	LCTY	AD		00				0		1397	Europe/Andorra	1993-12-23
+3040038	Les Pardines	Les Pardines		42.58333	1.48333	T	SLP	AD		00				0		1809	Europe/Andorra	1993-12-23
+3040039	Les Pardines	Les Pardines		42.43333	1.46667	S	HUTS	AD		00				0		1113	Europe/Andorra	1993-12-23
+3040040	Les Obagues	Les Obagues		42.58333	1.48333	L	LCTY	AD		00				0		1809	Europe/Andorra	1993-12-23
+3040041	Les Neres	Les Neres		42.55	1.56667	A	ADMD	AD		00				0		1828	Europe/Andorra	1993-12-23
+3040042	Les Molleres	Les Molleres		42.55	1.53333	L	LCTY	AD		00				0		1593	Europe/Andorra	1993-12-23
+3040043	Les Majobarnes	Les Majobarnes		42.55	1.48333	L	LCTY	AD		00				0		1548	Europe/Andorra	1993-12-23
+3040044	Les Llanasques	Les Llanasques		42.58333	1.58333	L	LCTY	AD		00				0		1993	Europe/Andorra	1993-12-23
+3040045	Les Forques	Les Forques		42.55	1.53333	L	LCTY	AD		00				0		1593	Europe/Andorra	1993-12-23
+3040046	Les Fonts	Les Fonts		42.6	1.6	T	UPLD	AD		00				0		2143	Europe/Andorra	1993-12-23
+3040047	Les Fonts	Les Fonts		42.6	1.48333	L	LCTY	AD		00				0		2441	Europe/Andorra	1993-12-23
+3040048	Les Feixes	Les Feixes		42.55	1.43333	L	LCTY	AD		00				0		1949	Europe/Andorra	1993-12-23
+3040049	Les Feixes	Les Feixes		42.53333	1.46667	L	LCTY	AD		00				0		1846	Europe/Andorra	1993-12-23
+3040050	Les Fargues	Les Fargues		42.48333	1.6	S	ANS	AD		00				0		2250	Europe/Andorra	1993-12-23
+3040051	les Escaldes	les Escaldes	Ehskal'des-Ehndzhordani,Escaldes,Escaldes-Engordany,Les Escaldes,esukarudesu=engorudani jiao qu,lai sai si ka er de-en ge er da,ЭÑкальдеÑ-Энджордани,エスカルデスï¼ã‚¨ãƒ³ã‚´ãƒ«ãƒ€ãƒ‹æ•™åŒº,èŠå¡žæ–¯å¡çˆ¾å¾·-æ©æˆˆçˆ¾é”,èŠå¡žæ–¯å¡çˆ¾å¾·ï¼æ©æˆˆçˆ¾é”	42.50729	1.53414	P	PPLA	AD		08				15853		1350	Europe/Andorra	2008-10-15
+3040052	Les Deveses	Les Deveses		42.53333	1.65	A	ADMD	AD		00				0		2508	Europe/Andorra	1993-12-23
+3040053	Les Costes	Les Costes		42.51667	1.55	A	ADMD	AD		00				0		1322	Europe/Andorra	1993-12-23
+3040054	Les Costeres	Les Costeres		42.53333	1.53333	L	LCTY	AD		00				0		1521	Europe/Andorra	1993-12-23
+3040055	Les Comelletes	Les Comelletes		42.48333	1.46667	L	LCTY	AD		00				0		1148	Europe/Andorra	1993-12-23
+3040056	Les Comarques	Les Comarques		42.55	1.51667	L	LCTY	AD		00				0		1397	Europe/Andorra	1993-12-23
+3040057	Les Colleroles	Les Colleroles		42.58333	1.6	T	SLP	AD		00				0		1828	Europe/Andorra	1993-12-23
+3040058	Les Codolles	Les Codolles		42.53333	1.51667	L	LCTY	AD		00				0		1361	Europe/Andorra	1993-12-23
+3040059	L’Escobar	L'Escobar		42.61667	1.68333	L	LCTY	AD		00				0		2406	Europe/Andorra	1993-12-23
+3040060	Les Claperes	Les Claperes		42.55	1.5	L	LCTY	AD		00				0		1292	Europe/Andorra	1993-12-23
+3040061	Les Carboneres	Les Carboneres		42.48333	1.46667	L	LCTY	AD		00				0		1148	Europe/Andorra	1993-12-23
+3040062	Les Canyorques	Les Canyorques		42.58333	1.43333	T	SLP	AD		00				0		2412	Europe/Andorra	1993-12-23
+3040063	Les Canals	Les Canals		42.58333	1.58333	L	LCTY	AD		00				0		1993	Europe/Andorra	1993-12-23
+3040064	Les Canaletes	Les Canaletes		42.6	1.45	T	RKS	AD		00				0		2174	Europe/Andorra	1993-12-23
+3040065	Les Canadilles	Les Canadilles		42.48333	1.48333	H	STM	AD		00				0		981	Europe/Andorra	1993-12-23
+3040066	Les Bordes	Les Bordes		42.58333	1.63333	S	HUTS	AD		00				0		1722	Europe/Andorra	1993-12-23
+3040067	Les Bons	Les Bons	Els Bons	42.53873	1.58649	P	PPL	AD	AD	03				0		1490	Europe/Andorra	2007-04-16
+3040068	Les Bartigues	Les Bartigues		42.6	1.53333	L	LCTY	AD		00				0		1695	Europe/Andorra	1993-12-23
+3040069	Les Barreres	Les Barreres		42.55	1.6	L	LCTY	AD		00				0		2210	Europe/Andorra	1993-12-23
+3040070	Les Barreres	Les Barreres		42.53333	1.53333	L	LCTY	AD		00				0		1521	Europe/Andorra	1993-12-23
+3040071	Les Bagelles	Les Bagelles		42.46667	1.5	L	LCTY	AD		00				0		1383	Europe/Andorra	1993-12-23
+3040072	Les Aubes	Les Aubes		42.51667	1.55	L	LCTY	AD		00				0		1322	Europe/Andorra	1993-12-23
+3040073	Les Aspades	Les Aspades		42.56667	1.55	L	LCTY	AD		00				0		1996	Europe/Andorra	1993-12-23
+3040074	Les Angleves	Les Angleves		42.53333	1.53333	L	LCTY	AD		00				0		1521	Europe/Andorra	1993-12-23
+3040075	Les Allaus	Les Allaus		42.63333	1.53333	L	LCTY	AD		00				0		2072	Europe/Andorra	1993-12-23
+3040076	Les Agols	Les Agols		42.51667	1.6	A	ADMD	AD		00				0		2085	Europe/Andorra	1993-12-23
+3040077	Les Abelletes	Les Abelletes		42.53333	1.73333	L	LCTY	AD		00				0		2300	Europe/Andorra	1993-12-23
+3040078	L’Ensegur	L'Ensegur		42.58333	1.53333	A	ADMD	AD		00				0		1924	Europe/Andorra	1993-12-23
+3040079	L’Avetar	L'Avetar		42.6	1.68333	L	LCTY	AD		00				0		2089	Europe/Andorra	1993-12-23
+3040080	Planell de Laverdú	Planell de Laverdu		42.63333	1.53333	T	UPLD	AD		00				0		2072	Europe/Andorra	1993-12-23
+3040081	Laverdú	Laverdu		42.63333	1.53333	L	LCTY	AD		00				0		2072	Europe/Andorra	1993-12-23
+3040082	La Vaquerissa	La Vaquerissa		42.55	1.45	L	LCTY	AD		00				0		1788	Europe/Andorra	1993-12-23
+3040083	L’Ausany	L'Ausany		42.61667	1.53333	L	LCTY	AD		00				0		1609	Europe/Andorra	1993-12-23
+3040084	La Uïna	La Uina		42.55	1.51667	A	ADMD	AD		00				0		1397	Europe/Andorra	1993-12-23
+3040085	La Trava	La Trava		42.58333	1.61667	L	LCTY	AD		00				0		1707	Europe/Andorra	1993-12-23
+3040086	La Trava	La Trava		42.56667	1.53333	L	GRAZ	AD		00				0		1669	Europe/Andorra	1993-12-23
+3040087	La Tosa	La Tosa		42.56667	1.46667	L	LCTY	AD		00				0		1673	Europe/Andorra	1993-12-23
+3040088	L’Assalador	L'Assalador		42.5	1.43333	L	GRAZ	AD		00				0		1654	Europe/Andorra	1993-12-23
+3040089	L’Asparró	L'Asparro		42.48333	1.5	T	PK	AD		00				0		1631	Europe/Andorra	1993-12-23
+3040090	La Solaneta	La Solaneta		42.53333	1.53333	L	LCTY	AD		00				0		1521	Europe/Andorra	1993-12-23
+3040091	La Solanella	La Solanella		42.46667	1.5	L	LCTY	AD		00				0		1383	Europe/Andorra	1993-12-23
+3040092	La Solana	La Solana		42.58333	1.76667	A	ADMD	AD		00				0		1945	Europe/Andorra	1993-12-23
+3040093	La Serreta	La Serreta		42.58333	1.61667	T	SPUR	AD		00				0		1707	Europe/Andorra	1993-12-23
+3040094	La Serradora	La Serradora		42.46667	1.46667	L	LCTY	AD		00				0		1340	Europe/Andorra	1993-12-23
+3040095	La Serra	La Serra		42.45204	1.49609	S	HUTS	AD		00				0		1270	Europe/Andorra	2011-04-19
+3040096	La Senyoreta	La Senyoreta		42.45	1.48333	A	ADMD	AD		00				0		1111	Europe/Andorra	1993-12-23
+3040097	L’Artiga	L'Artiga		42.56946	1.60243	L	LCTY	AD		00				0		1655	Europe/Andorra	2011-04-19
+3040098	L’Artic	L'Artic		42.5	1.46667	L	LCTY	AD		00				0		1678	Europe/Andorra	1993-12-23
+3040099	La Rovira	La Rovira		42.45	1.46667	L	LCTY	AD		00				0		935	Europe/Andorra	1993-12-23
+3040100	La Roca	La Roca		42.55	1.58333	L	LCTY	AD		00				0		1499	Europe/Andorra	1993-12-23
+3040101	L’Armiana	L'Armiana		42.58333	1.6	A	ADMD	AD		00				0		1828	Europe/Andorra	1993-12-23
+3040102	La Riberola	La Riberola		42.45	1.48333	L	LCTY	AD		00				0		1111	Europe/Andorra	1993-12-23
+3040103	La Rabassa	La Rabassa		42.63333	1.55	A	ADMD	AD		00				0		2053	Europe/Andorra	1993-12-23
+3040104	La Rabassa	La Rabassa	Bois de la Rabassa,Bois de la Rabossa,La Rabassa	42.43333	1.51667	A	ADMD	AD	AD	00				0		2031	Europe/Andorra	2011-11-05
+3040105	La Quera	La Quera		42.51667	1.51667	L	LCTY	AD		00				0		1265	Europe/Andorra	1993-12-23
+3040106	La Presó	La Preso		42.61667	1.56667	L	LCTY	AD		00				0		2228	Europe/Andorra	1993-12-23
+3040107	La Posa	La Posa		42.53333	1.6	L	LCTY	AD		00				0		1888	Europe/Andorra	1993-12-23
+3040108	La Portelleta	La Portelleta		42.48333	1.65	L	LCTY	AD		00				0		2658	Europe/Andorra	1993-12-23
+3040109	La Portella	La Portella		42.55218	1.62761	T	PK	AD		00				0		2364	Europe/Andorra	2011-04-19
+3040110	La Portella	La Portella		42.45	1.5	T	PK	AD		00				0		1614	Europe/Andorra	1993-12-23
+3040111	La Portella	La Portella		42.56667	1.71667	A	ADMD	AD		00				0		2219	Europe/Andorra	1993-12-23
+3040112	La Polguera	La Polguera		42.56667	1.58333	L	LCTY	AD		00				0		1919	Europe/Andorra	1993-12-23
+3040113	La Pleta	La Pleta		42.55	1.43333	S	HUTS	AD		00				0		1949	Europe/Andorra	1993-12-23
+3040114	La Planada	La Planada		42.6	1.6	T	UPLD	AD		00				0		2143	Europe/Andorra	1993-12-23
+3040115	La Plana	La Plana		42.51667	1.51667	T	UPLD	AD		00				0		1265	Europe/Andorra	1993-12-23
+3040116	La Plana	La Plana		42.5	1.55	L	LCTY	AD		00				0		1566	Europe/Andorra	1993-12-23
+3040117	La Pinatella	La Pinatella		42.53333	1.6	L	LCTY	AD		00				0		1888	Europe/Andorra	1993-12-23
+3040118	La Peracaus	La Peracaus		42.56667	1.6	L	LCTY	AD		00				0		1655	Europe/Andorra	1993-12-23
+3040119	La Pera	La Pera		42.56667	1.46667	L	LCTY	AD		00				0		1673	Europe/Andorra	1993-12-23
+3040120	La Peguera	La Peguera		42.45	1.53333	A	ADMD	AD		00				0		1859	Europe/Andorra	1993-12-23
+3040121	La Pedregosa	La Pedregosa		42.58333	1.61667	L	LCTY	AD		00				0		1707	Europe/Andorra	1993-12-23
+3040122	La Passera	La Passera		42.6	1.53333	H	STM	AD		00				0		1695	Europe/Andorra	1993-12-23
+3040123	La Palomera	La Palomera		42.58333	1.78333	L	LCTY	AD		00				0		1694	Europe/Andorra	1993-12-23
+3040124	L’Angonella	L'Angonella		42.6	1.5	A	ADMD	AD		00				0		1923	Europe/Andorra	1993-12-23
+3040125	L’Andorrana	L'Andorrana		42.55	1.43333	L	LCTY	AD		00				0		1949	Europe/Andorra	1993-12-23
+3040126	La Muga	La Muga		42.48333	1.65	L	LCTY	AD		00				0		2658	Europe/Andorra	1993-12-23
+3040127	La Molina	La Molina		42.45	1.51667	L	LCTY	AD		00				0		1790	Europe/Andorra	1993-12-23
+3040128	La Molina	La Molina		42.51667	1.6	A	ADMD	AD		00				0		2085	Europe/Andorra	1993-12-23
+3040129	La Moixella	La Moixella		42.43333	1.46667	S	HUTS	AD		00				0		1113	Europe/Andorra	1993-12-23
+3040130	La Mentirosa	La Mentirosa		42.43333	1.51667	L	LCTY	AD		00				0		2031	Europe/Andorra	1993-12-23
+3040131	Parròquia de la Massana	Parroquia de la Massana	La Massana,Parroquia de la Massana,Parròquia de la Massana,la Massana	42.56667	1.48333	A	ADM1	AD		04				8953		1508	Europe/Andorra	2008-03-17
+3040132	la Massana	la Massana	La Macana,La Massana,La Maçana,La-Massana,la Massana,ma sa na,Ла-МаÑÑана,ラ・マサナ教区,马è¨çº³	42.54499	1.51483	P	PPLA	AD		04				7211		1257	Europe/Andorra	2008-10-15
+3040133	La Margineda	La Margineda		42.48333	1.5	A	ADMD	AD		00				0		1631	Europe/Andorra	1993-12-23
+3040134	La Mandurana	La Mandurana		42.56667	1.61667	A	ADMD	AD		00				0		1920	Europe/Andorra	1993-12-23
+3040135	L’Alzinar	L'Alzinar		42.48333	1.5	L	LCTY	AD		00				0		1631	Europe/Andorra	1993-12-23
+3040136	La Lomera	La Lomera		42.46667	1.48333	L	LCTY	AD		00				0		1134	Europe/Andorra	1993-12-23
+3040137	La Llosada	La Llosada		42.55	1.63333	A	ADMD	AD		00				0		2336	Europe/Andorra	1993-12-23
+3040138	Serrat de La Llonga	Serrat de La Llonga		42.56667	1.51667	T	RDGE	AD		00				0		1500	Europe/Andorra	1993-12-23
+3040139	La Llonga	La Llonga		42.56667	1.51667	A	ADMD	AD		00				0		1500	Europe/Andorra	1993-12-23
+3040140	l'Aldosa	l'Aldosa		42.58333	1.63333	P	PPL	AD		02				195		1722	Europe/Andorra	2007-04-29
+3040141	l'Aldosa	l'Aldosa		42.54391	1.52289	P	PPL	AD		04				594		1397	Europe/Andorra	2007-04-29
+3040142	L’Airola	L'Airola		42.46667	1.46667	L	LCTY	AD		00				0		1340	Europe/Andorra	1993-12-23
+3040143	La Gonarda	La Gonarda		42.55	1.53333	L	LCTY	AD		00				0		1593	Europe/Andorra	1993-12-23
+3040144	La Gonarda	La Gonarda		42.55	1.53333	A	ADMD	AD		00				0		1593	Europe/Andorra	1993-12-23
+3040145	La Ginebrosa	La Ginebrosa		42.55	1.51667	L	LCTY	AD		00				0		1397	Europe/Andorra	1993-12-23
+3040146	La Garganta	La Garganta		42.53333	1.6	L	LCTY	AD		00				0		1888	Europe/Andorra	1993-12-23
+3040147	La Gargallera	La Gargallera		42.48333	1.45	L	LCTY	AD		00				0		1195	Europe/Andorra	1993-12-23
+3040148	La Fonteta	La Fonteta		42.58333	1.46667	L	LCTY	AD		00				0		1643	Europe/Andorra	1993-12-23
+3040149	La Fita	La Fita		42.55	1.45	L	LCTY	AD		00				0		1788	Europe/Andorra	1993-12-23
+3040150	La Cuina	La Cuina		42.56667	1.48333	T	SPUR	AD		00				0		1508	Europe/Andorra	1993-12-23
+3040151	La Creu de les Portes	La Creu de les Portes		42.48333	1.48333	L	LCTY	AD		00				0		981	Europe/Andorra	1993-12-23
+3040152	La Costa	La Costa		42.57834	1.64324	P	PPL	AD		02				0		1737	Europe/Andorra	2011-04-19
+3040153	La Coruvilla	La Coruvilla		42.58333	1.46667	A	ADMD	AD		00				0		1643	Europe/Andorra	1993-12-23
+3040154	La Cortinada	La Cortinada	La Cortinada	42.57601	1.51896	P	PPL	AD		05				0		1722	Europe/Andorra	2011-11-05
+3040155	La Cortada	La Cortada		42.45	1.5	L	LCTY	AD		00				0		1614	Europe/Andorra	1993-12-23
+3040156	La Comella	La Comella		42.51667	1.68333	L	LCTY	AD		00				0		2352	Europe/Andorra	1993-12-23
+3040157	La Comella	La Comella		42.5	1.53333	S	HUTS	AD		00				0		1574	Europe/Andorra	1993-12-23
+3040158	La Comarqueta	La Comarqueta		42.58333	1.71667	L	LCTY	AD		00				0		2553	Europe/Andorra	1993-12-23
+3040159	La Comarqueta	La Comarqueta		42.48333	1.63333	L	LCTY	AD		00				0		2296	Europe/Andorra	1993-12-23
+3040160	La Colilla	La Colilla		42.53333	1.6	L	LCTY	AD		00				0		1888	Europe/Andorra	1993-12-23
+3040161	La Colilla	La Colilla		42.5	1.58333	L	LCTY	AD		00				0		1888	Europe/Andorra	1993-12-23
+3040162	La Clota	La Clota		42.56667	1.53333	L	LCTY	AD		00				0		1669	Europe/Andorra	1993-12-23
+3040163	La Caubella	La Caubella		42.58333	1.48333	L	CLG	AD		00				0		1809	Europe/Andorra	1993-12-23
+3040164	La Castelleta	La Castelleta		42.53333	1.51667	T	SPUR	AD		00				0		1361	Europe/Andorra	1993-12-23
+3040165	La Carbonera	La Carbonera		42.46667	1.63333	L	LCTY	AD		00				0		2619	Europe/Andorra	1993-12-23
+3040166	La Caolla	La Caolla		42.5	1.61667	T	SPUR	AD		00				0		2560	Europe/Andorra	1993-12-23
+3040167	La Callisa	La Callisa		42.56667	1.48333	S	BDG	AD		00				0		1508	Europe/Andorra	1993-12-23
+3040168	La Cabeça	La Cabeca		42.48333	1.45	L	LCTY	AD		00				0		1195	Europe/Andorra	1994-04-16
+3040169	La Cabanella	La Cabanella		42.51667	1.46667	A	ADMD	AD		00				0		1840	Europe/Andorra	1993-12-23
+3040170	La Burna	La Burna		42.6	1.48333	T	CRQ	AD		00				0		2441	Europe/Andorra	1993-12-23
+3040171	La Borda Nova	La Borda Nova		42.61667	1.53333	S	HUT	AD		00				0		1609	Europe/Andorra	1993-12-23
+3040172	La Bor	La Bor		42.55	1.58333	A	ADMD	AD		00				0		1499	Europe/Andorra	1993-12-23
+3040173	La Boixosa	La Boixosa		42.56667	1.53333	L	LCTY	AD		00				0		1669	Europe/Andorra	1993-12-23
+3040174	La Beçosa	La Becosa		42.61667	1.55	L	LCTY	AD		00				0		2007	Europe/Andorra	1994-04-16
+3040175	La Bauma	La Bauma		42.48333	1.61667	S	CAVE	AD		00				0		2217	Europe/Andorra	1993-12-23
+3040176	La Basseta	La Basseta		42.48333	1.65	H	LK	AD		00				0		2658	Europe/Andorra	1993-12-23
+3040177	La Basera	La Basera		42.58333	1.65	L	LCTY	AD		00				0		1767	Europe/Andorra	1993-12-23
+3040178	La Bartra del Ganxo	La Bartra del Ganxo		42.48333	1.46667	L	LCTY	AD		00				0		1148	Europe/Andorra	1993-12-23
+3040179	La Bartra	La Bartra		42.51667	1.55	L	LCTY	AD		00				0		1322	Europe/Andorra	1993-12-23
+3040180	La Bartra	La Bartra		42.46667	1.46667	L	LCTY	AD		00				0		1340	Europe/Andorra	1993-12-23
+3040181	La Bartra	La Bartra	La Barta,La Bartra	42.51667	1.56667	A	ADMD	AD	AD	00				0		1759	Europe/Andorra	2011-11-05
+3040182	L’Abarsetar	L'Abarsetar		42.61667	1.51667	L	LCTY	AD		00				0		1716	Europe/Andorra	1993-12-23
+3040183	L’Abarsetar	L'Abarsetar		42.53333	1.61667	L	LCTY	AD		00				0		2237	Europe/Andorra	1993-12-23
+3040184	La Baladosa	La Baladosa		42.6	1.68333	L	LCTY	AD		00				0		2089	Europe/Andorra	1993-12-23
+3040185	Tosa de Juclar	Tosa de Juclar		42.6	1.71667	T	UPLD	AD		00				0		2516	Europe/Andorra	1993-12-23
+3040186	Solana de Juclar	Solana de Juclar		42.6	1.7	T	SLP	AD		00				0		2354	Europe/Andorra	1993-12-23
+3040187	Riu de Juclar	Riu de Juclar		42.60124	1.69807	H	STM	AD		00				0		2147	Europe/Andorra	2011-04-19
+3040188	Pleta de Juclar	Pleta de Juclar		42.6	1.71667	L	GRAZ	AD		00				0		2516	Europe/Andorra	1993-12-23
+3040189	Obaga de Juclar	Obaga de Juclar		42.61667	1.7	T	SLP	AD		00				0		2285	Europe/Andorra	1993-12-23
+3040190	Collada de Juclar	Collada de Juclar	Col de Joucla,Col de l' Albe,Col de l’ Albe,Collada de Juclar,Port de Jogela,Port de Joucla	42.61667	1.73333	T	PASS	AD		00				0		2508	Europe/Andorra	2011-11-05
+3040191	Canals de Juclar	Canals de Juclar		42.6	1.71667	H	RVN	AD		00				0		2516	Europe/Andorra	1993-12-23
+3040192	Camí de Juclar	Cami de Juclar		42.6	1.7	R	TRL	AD		00				0		2354	Europe/Andorra	1993-12-23
+3040193	Alt de Juclar	Alt de Juclar		42.61667	1.7	T	RDGE	AD		00				0		2285	Europe/Andorra	1993-12-23
+3040194	Juclar	Juclar		42.6	1.71667	A	ADMD	AD		00				0		2516	Europe/Andorra	1993-12-23
+3040195	Carretera de la Juberrussa	Carretera de la Juberrussa		42.45	1.48333	R	RD	AD		00				0		1111	Europe/Andorra	1993-12-23
+3040196	Canal de la Juberrussa	Canal de la Juberrussa		42.43333	1.48333	H	STM	AD		00				0		1228	Europe/Andorra	1993-12-23
+3040197	Bosc de la Juberrussa	Bosc de la Juberrussa		42.43333	1.48333	V	FRST	AD		00				0		1228	Europe/Andorra	1993-12-23
+3040198	Bordes de la Juberrussa	Bordes de la Juberrussa		42.43333	1.48333	S	FRM	AD		00				0		1228	Europe/Andorra	1993-12-23
+3040199	Juberrussa	Juberrussa		42.43333	1.48333	A	ADMD	AD		00				0		1228	Europe/Andorra	1993-12-23
+3040200	Juberri	Juberri	Juberri,Juverri	42.44069	1.48972	P	PPL	AD		06				0		1460	Europe/Andorra	2011-11-05
+3040201	Font de la Jubanya	Font de la Jubanya		42.58333	1.45	H	SPNG	AD		00				0		2156	Europe/Andorra	1993-12-23
+3040202	Coll Jovell	Coll Jovell		42.45	1.53333	T	SPUR	AD		00				0		1859	Europe/Andorra	1993-12-23
+3040203	Coll Jovell	Coll Jovell		42.5	1.56667	T	PK	AD		00				0		1776	Europe/Andorra	1993-12-23
+3040204	Coll Jovell	Coll Jovell		42.48333	1.48333	T	PK	AD		00				0		981	Europe/Andorra	1993-12-23
+3040205	Jovell	Jovell		42.58333	1.63333	L	LCTY	AD		00				0		1722	Europe/Andorra	1993-12-23
+3040206	Coll de Jou	Coll de Jou		42.51667	1.55	T	SPUR	AD		00				0		1322	Europe/Andorra	1993-12-23
+3040207	Coll de Jou	Coll de Jou		42.45	1.46667	T	PASS	AD		00				0		935	Europe/Andorra	1993-12-23
+3040208	Canal del Jou	Canal del Jou		42.56667	1.5	H	STM	AD		00				0		1636	Europe/Andorra	1993-12-23
+3040209	Camí del Jou	Cami del Jou		42.56667	1.5	R	TRL	AD		00				0		1636	Europe/Andorra	1993-12-23
+3040210	Bosc del Jou	Bosc del Jou		42.56667	1.51667	V	FRST	AD		00				0		1500	Europe/Andorra	1993-12-23
+3040211	Solana del Jordà	Solana del Jorda		42.51667	1.6	T	SLP	AD		00				0		2085	Europe/Andorra	1993-12-23
+3040212	Borda del Joansaus	Borda del Joansaus		42.58333	1.65	S	HUT	AD		00				0		1767	Europe/Andorra	1993-12-23
+3040213	Portella de Joan Antoni	Portella de Joan Antoni		42.51195	1.70887	T	PASS	AD		00				0		2550	Europe/Andorra	2011-04-19
+3040214	Pleta de Jes Agols	Pleta de Jes Agols		42.51667	1.6	L	GRAZ	AD		00				0		2085	Europe/Andorra	1993-12-23
+3040215	Borda del Jep	Borda del Jep	Borda del Gep,Borda del Jep	42.56667	1.58333	S	HUT	AD	AD	00				0		1919	Europe/Andorra	2011-11-05
+3040216	Borda del Jarca	Borda del Jarca		42.56667	1.58333	S	HUT	AD		00				0		1919	Europe/Andorra	1993-12-23
+3040217	Borda del Jarca	Borda del Jarca		42.55	1.6	S	HUT	AD		00				0		2210	Europe/Andorra	1993-12-23
+3040218	Borda del Janramon	Borda del Janramon		42.56667	1.58333	S	HUT	AD		00				0		1919	Europe/Andorra	1993-12-23
+3040219	Turó de Jan	Turo de Jan		42.61667	1.63333	T	SPUR	AD		00				0		2331	Europe/Andorra	1993-12-23
+3040220	Riu de Jan	Riu de Jan		42.61667	1.63333	H	STM	AD		00				0		2331	Europe/Andorra	1993-12-23
+3040221	Pala de Jan	Pala de Jan		42.61667	1.63333	T	CLF	AD		00				0		2331	Europe/Andorra	1993-12-23
+3040222	Cóms de Jan	Coms de Jan		42.61667	1.63333	H	LK	AD		00				0		2331	Europe/Andorra	1993-12-23
+3040223	Collada de Jan	Collada de Jan	Collada de Jan	42.61667	1.63333	T	PASS	AD		00				0		2331	Europe/Andorra	2011-11-05
+3040224	Estany de l’ Isla	Estany de l' Isla		42.61667	1.68333	H	LK	AD		00				0		2406	Europe/Andorra	1993-12-23
+3040225	Font dels Isards	Font dels Isards		42.58333	1.7	H	SPNG	AD		00				0		2584	Europe/Andorra	1993-12-23
+3040226	Costa dels Isards	Costa dels Isards		42.58333	1.6	T	SLP	AD		00				0		1828	Europe/Andorra	1993-12-23
+3040227	Coll dels Isards	Coll dels Isards		42.51831	1.73762	T	PASS	AD		00				0		2659	Europe/Andorra	2011-04-19
+3040228	Canal dels Isards	Canal dels Isards		42.5	1.66667	H	RVN	AD		00				0		2441	Europe/Andorra	1993-12-23
+3040229	Canal de l’ Isard	Canal de l' Isard		42.58333	1.46667	H	STM	AD		00				0		1643	Europe/Andorra	1993-12-23
+3040230	Pla de l’ Ingla	Pla de l' Ingla		42.48333	1.61667	T	UPLD	AD		00				0		2217	Europe/Andorra	1993-12-23
+3040231	Collet de l’ Infern	Collet de l' Infern		42.48333	1.6	T	PASS	AD		00				0		2250	Europe/Andorra	1993-12-23
+3040232	Canal de l’ Infern	Canal de l' Infern		42.53333	1.6	H	STM	AD		00				0		1888	Europe/Andorra	1993-12-23
+3040233	Torrent dels Indrets	Torrent dels Indrets		42.48333	1.45	H	STM	AD		00				0		1195	Europe/Andorra	1993-12-23
+3040234	Riu d’ Incles	Riu d' Incles		42.60159	1.68721	H	STM	AD		00				0		2014	Europe/Andorra	2011-04-19
+3040235	Prats d’ Incles	Prats d' Incles		42.6	1.66667	L	GRAZ	AD		00				0		1858	Europe/Andorra	1993-12-23
+3040236	Port de Fontargente	Port de Fontargente	Port d' Incles,Port de Fontargent,Port de Fontargente,Port d’ Incles	42.61667	1.71667	T	PASS	AD		00				0		2352	Europe/Andorra	2011-11-05
+3040237	Pont d’ Incles	Pont d' Incles		42.58333	1.66667	S	BDG	AD		00				0		2159	Europe/Andorra	1993-12-23
+3040238	Camí d’ Incles	Cami d' Incles		42.6	1.66667	R	TRL	AD		00				0		1858	Europe/Andorra	1993-12-23
+3040239	Bosc d’ Incles	Bosc d' Incles		42.58333	1.66667	V	FRST	AD		00				0		2159	Europe/Andorra	1993-12-23
+3040240	Estany de l’ Illa	Estany de l' Illa		42.49785	1.65852	H	RSV	AD		00				0		2553	Europe/Andorra	2011-04-19
+3040241	Obagues de la Iesca	Obagues de la Iesca		42.48333	1.43333	T	SLP	AD		00				0		1938	Europe/Andorra	1993-12-23
+3040242	Bosc de l’ Hoste	Bosc de l' Hoste		42.55	1.68333	V	FRST	AD		00				0		2254	Europe/Andorra	1993-12-23
+3040243	Bosc de l’ Hostal del Poll	Bosc de l' Hostal del Poll		42.61667	1.63333	V	FRST	AD		00				0		2331	Europe/Andorra	1993-12-23
+3040244	Riu dels Hortons	Riu dels Hortons		42.51667	1.46667	H	STM	AD		00				0		1840	Europe/Andorra	1993-12-23
+3040245	Bosc dels Hortons	Bosc dels Hortons		42.53333	1.55	V	FRST	AD		00				0		1344	Europe/Andorra	1993-12-23
+3040246	Torrent dels Hortells	Torrent dels Hortells		42.45	1.48333	H	STM	AD		00				0		1111	Europe/Andorra	1993-12-23
+3040247	Serra de l’ Hortell	Serra de l' Hortell		42.61667	1.51667	T	MT	AD		00				0		1716	Europe/Andorra	1993-12-23
+3040248	Pic de l’ Hortell	Pic de l' Hortell		42.61914	1.50815	T	PK	AD		00				0		2390	Europe/Andorra	2011-04-19
+3040249	Torrent dels Hortals	Torrent dels Hortals		42.53333	1.58333	H	STM	AD		00				0		1571	Europe/Andorra	1993-12-23
+3040250	Serra de l’ Honor	Serra de l' Honor		42.53333	1.51667	T	SPUR	AD		00				0		1361	Europe/Andorra	1993-12-23
+3040251	Roc del’ Home Dret	Roc del' Home Dret		42.58333	1.66667	T	SPUR	AD		00				0		2159	Europe/Andorra	1993-12-23
+3040252	Roca Herbosa	Roca Herbosa		42.48333	1.56667	T	RK	AD		00				0		2231	Europe/Andorra	1993-12-23
+3040253	Pleta de Guitard	Pleta de Guitard	Pleta de Guitard,Pleta de Guitart	42.53333	1.6	L	GRAZ	AD	AD	00				0		1888	Europe/Andorra	2011-11-05
+3040254	Cortal del Guitard	Cortal del Guitard	Cortal del Guitard,Cortal del Guitart	42.45	1.5	S	CRRL	AD	AD	00				0		1614	Europe/Andorra	2011-11-05
+3040255	Tartera de les Guineus	Tartera de les Guineus		42.56667	1.68333	T	TAL	AD		00				0		2340	Europe/Andorra	1993-12-23
+3040256	Roc de la Guilla	Roc de la Guilla		42.51667	1.56667	T	RK	AD		00				0		1759	Europe/Andorra	1993-12-23
+3040257	Bony de les Guardioles	Bony de les Guardioles		42.55	1.51667	T	SPUR	AD		00				0		1397	Europe/Andorra	1993-12-23
+3040258	Serra de la Guardiola	Serra de la Guardiola		42.58081	1.71111	T	RDGE	AD		00				0		2544	Europe/Andorra	2011-04-19
+3040259	Obaga de la Guardiola	Obaga de la Guardiola		42.56667	1.68333	T	SLP	AD		00				0		2340	Europe/Andorra	1993-12-23
+3040260	Planell de la Guàrdia	Planell de la Guardia		42.61667	1.51667	T	UPLD	AD		00				0		1716	Europe/Andorra	1993-12-23
+3040261	Roques Grosses	Roques Grosses		42.58333	1.66667	T	RKS	AD		00				0		2159	Europe/Andorra	1993-12-23
+3040262	Riba Grossa	Riba Grossa		42.55	1.6	T	TAL	AD		00				0		2210	Europe/Andorra	1993-12-23
+3040263	Roc Gros	Roc Gros		42.58333	1.48333	T	RK	AD		00				0		1809	Europe/Andorra	1993-12-23
+3040264	Riu Gros	Riu Gros		42.56667	1.66667	H	STM	AD		00				0		1938	Europe/Andorra	1993-12-23
+3040265	Alt del Griu	Alt del Griu		42.52534	1.65114	T	MT	AD		00				0		2508	Europe/Andorra	2011-04-19
+3040266	Riu del Grill	Riu del Grill		42.51667	1.6	H	STM	AD		00				0		2085	Europe/Andorra	1993-12-23
+3040267	Font de les Greixes	Font de les Greixes		42.46667	1.45	H	SPNG	AD		00				0		1562	Europe/Andorra	1993-12-23
+3040268	Clot de les Greixes	Clot de les Greixes		42.46667	1.45	H	RVN	AD		00				0		1562	Europe/Andorra	1993-12-23
+3040269	Camí de les Gravades	Cami de les Gravades		42.53333	1.51667	R	TRL	AD		00				0		1361	Europe/Andorra	1993-12-23
+3040270	Clot dels Gravaders	Clot dels Gravaders		42.46667	1.55	H	RVN	AD		00				0		2341	Europe/Andorra	1993-12-23
+3040271	Pleta dels Graus	Pleta dels Graus		42.48333	1.56667	L	GRAZ	AD		00				0		2231	Europe/Andorra	1993-12-23
+3040272	Grau Roig	Grau Roig		42.53333	1.7	S	RSRT	AD		03				0		2357	Europe/Andorra	2010-01-11
+3040273	Obaga de Graupont	Obaga de Graupont		42.48333	1.46667	T	SLP	AD		00				0		1148	Europe/Andorra	1993-12-23
+3040274	Clot de Graupont	Clot de Graupont		42.48333	1.46667	H	RVN	AD		00				0		1148	Europe/Andorra	1993-12-23
+3040275	Grau d’Incles	Grau d'Incles		42.58333	1.65	L	LCTY	AD		00				0		1767	Europe/Andorra	1993-12-23
+3040276	Grau del Cabrer	Grau del Cabrer		42.56667	1.71667	L	LCTY	AD		00				0		2219	Europe/Andorra	1993-12-23
+3040277	Plana del Grau	Plana del Grau		42.58333	1.51667	T	UPLD	AD		00				0		1722	Europe/Andorra	1993-12-23
+3040278	Costa del Grau	Costa del Grau		42.56667	1.6	T	SLP	AD		00				0		1655	Europe/Andorra	1993-12-23
+3040279	Canal del Grau	Canal del Grau		42.56667	1.6	H	STM	AD		00				0		1655	Europe/Andorra	1993-12-23
+3040280	Canal Gran de la Serrera	Canal Gran de la Serrera		42.61667	1.58333	H	RVN	AD		00				0		2374	Europe/Andorra	1993-12-23
+3040281	Canal Gran de la Grella	Canal Gran de la Grella		42.51667	1.51667	H	STM	AD		00				0		1265	Europe/Andorra	1993-12-23
+3040282	Planell Gran de la Cebollera	Planell Gran de la Cebollera		42.63333	1.58333	T	UPLD	AD		00				0		2470	Europe/Andorra	1993-12-23
+3040283	Costa de les Grandalles	Costa de les Grandalles		42.53333	1.7	T	SLP	AD		00				0		2357	Europe/Andorra	1993-12-23
+3040284	Planell Gran	Planell Gran		42.63333	1.55	T	UPLD	AD		00				0		2053	Europe/Andorra	1993-12-23
+3040285	Planell Gran	Planell Gran		42.58333	1.66667	T	UPLD	AD		00				0		2159	Europe/Andorra	1993-12-23
+3040286	Planell Gran	Planell Gran		42.56667	1.46667	T	UPLD	AD		00				0		1673	Europe/Andorra	1993-12-23
+3040287	Planell Gran	Planell Gran		42.55	1.68333	T	UPLD	AD		00				0		2254	Europe/Andorra	1993-12-23
+3040288	Planell Gran	Planell Gran		42.55	1.65	T	UPLD	AD		00				0		2432	Europe/Andorra	1993-12-23
+3040289	Planell Gran	Planell Gran		42.46667	1.56667	T	UPLD	AD		00				0		2365	Europe/Andorra	1993-12-23
+3040290	Costa Gran	Costa Gran		42.61667	1.61667	T	SLP	AD		00				0		2352	Europe/Andorra	1993-12-23
+3040291	Costa Gran	Costa Gran		42.6	1.61667	T	SLP	AD		00				0		2271	Europe/Andorra	1993-12-23
+3040292	Costa Gran	Costa Gran		42.51667	1.48333	T	SLP	AD		00				0		1839	Europe/Andorra	1993-12-23
+3040293	Canal Gran	Canal Gran		42.58333	1.46667	H	STM	AD		00				0		1643	Europe/Andorra	1993-12-23
+3040294	Canal Gran	Canal Gran		42.56667	1.51667	H	STM	AD		00				0		1500	Europe/Andorra	1993-12-23
+3040295	Canal Gran	Canal Gran		42.56667	1.48333	H	STM	AD		00				0		1508	Europe/Andorra	1993-12-23
+3040296	Canal Gran	Canal Gran		42.55	1.58333	H	STM	AD		00				0		1499	Europe/Andorra	1993-12-23
+3040297	Canal Gran	Canal Gran		42.55	1.5	H	STM	AD		00				0		1292	Europe/Andorra	1993-12-23
+3040298	Canal Gran	Canal Gran		42.5	1.63333	H	STM	AD		00				0		2545	Europe/Andorra	1993-12-23
+3040299	Canal Gran	Canal Gran		42.48333	1.48333	H	STM	AD		00				0		981	Europe/Andorra	1993-12-23
+3040300	Canal Gran	Canal Gran		42.46667	1.48333	H	STM	AD		00				0		1134	Europe/Andorra	1993-12-23
+3040301	Basera Gran	Basera Gran		42.5	1.48333	T	CLF	AD		00				0		1316	Europe/Andorra	1993-12-23
+3040302	Plana de Gral	Plana de Gral		42.58333	1.48333	T	UPLD	AD		00				0		1809	Europe/Andorra	1993-12-23
+3040303	Canya de les Grailes	Canya de les Grailes		42.48333	1.51667	S	CAVE	AD		00				0		2061	Europe/Andorra	1993-12-23
+3040304	Canya de les Grailes	Canya de les Grailes		42.46667	1.46667	S	CAVE	AD		00				0		1340	Europe/Andorra	1993-12-23
+3040305	Canal de les Grailes	Canal de les Grailes		42.5	1.61667	H	STM	AD		00				0		2560	Europe/Andorra	1993-12-23
+3040306	Roc del Grailer	Roc del Grailer		42.56667	1.51667	T	RK	AD		00				0		1500	Europe/Andorra	1993-12-23
+3040307	Tartera del Goter	Tartera del Goter		42.56667	1.73333	T	TAL	AD		00				0		2096	Europe/Andorra	1993-12-23
+3040308	Roc del Goter	Roc del Goter		42.56667	1.73333	T	CLF	AD		00				0		2096	Europe/Andorra	1993-12-23
+3040309	Pala del Goter	Pala del Goter		42.56667	1.73333	T	SLP	AD		00				0		2096	Europe/Andorra	1993-12-23
+3040310	Bosc de la Gonarda	Bosc de la Gonarda		42.55	1.53333	V	FRST	AD		00				0		1593	Europe/Andorra	1993-12-23
+3040311	Coll de Gomà	Coll de Goma		42.55	1.55	T	PASS	AD		00				0		2097	Europe/Andorra	1993-12-23
+3040312	Planell de Ginestar	Planell de Ginestar		42.6	1.55	T	UPLD	AD		00				0		2298	Europe/Andorra	1993-12-23
+3040313	Bony de la Ginebrera	Bony de la Ginebrera		42.45	1.46667	T	SPUR	AD		00				0		935	Europe/Andorra	1993-12-23
+3040314	Font del Ginebre	Font del Ginebre		42.43333	1.45	H	SPNG	AD		00				0		877	Europe/Andorra	1993-12-23
+3040315	Prat del Gilet	Prat del Gilet		42.51667	1.6	L	GRAZ	AD		00				0		2085	Europe/Andorra	1993-12-23
+3040316	Pla del Géspit	Pla del Gespit		42.55	1.61667	T	UPLD	AD		00				0		2206	Europe/Andorra	1993-12-23
+3040317	Pala del Géspit	Pala del Gespit		42.61667	1.55	T	SLP	AD		00				0		2007	Europe/Andorra	1993-12-23
+3040318	Pala del Géspit	Pala del Gespit		42.56667	1.55	T	SLP	AD		00				0		1996	Europe/Andorra	1993-12-23
+3040319	Borda del Germà	Borda del Germa		42.45	1.48333	S	FRM	AD		00				0		1111	Europe/Andorra	1993-12-23
+3040320	Costa de les Gerderes	Costa de les Gerderes		42.55	1.6	T	SLP	AD		00				0		2210	Europe/Andorra	1993-12-23
+3040321	Cortal del Genret	Cortal del Genret		42.45	1.5	S	CRRL	AD		00				0		1614	Europe/Andorra	1993-12-23
+3040322	Clot del Gel	Clot del Gel		42.51667	1.48333	H	RVN	AD		00				0		1839	Europe/Andorra	1993-12-23
+3040323	Canal del Gel	Canal del Gel		42.48333	1.46667	H	STM	AD		00				0		1148	Europe/Andorra	1993-12-23
+3040324	Solana de la Gaverna	Solana de la Gaverna		42.51667	1.6	T	SLP	AD		00				0		2085	Europe/Andorra	1993-12-23
+3040325	Font de la Gavatxa	Font de la Gavatxa		42.53333	1.73333	H	SPNG	AD		00				0		2300	Europe/Andorra	1993-12-23
+3040326	Borda del Gastó	Borda del Gasto		42.45	1.46667	S	HUT	AD		00				0		935	Europe/Andorra	1993-12-23
+3040327	Serrat de la Garriga	Serrat de la Garriga		42.53333	1.61667	T	SPUR	AD		00				0		2237	Europe/Andorra	1993-12-23
+3040328	Crestes de Gargantillar	Crestes de Gargantillar		42.50208	1.63061	T	RDGE	AD		00				0		2666	Europe/Andorra	2011-04-19
+3040329	Collades de Gargantillar	Collades de Gargantillar		42.5	1.65	T	PASS	AD		00				0		2542	Europe/Andorra	1993-12-23
+3040330	Clots de Gargantillar	Clots de Gargantillar		42.5	1.65	H	RVN	AD		00				0		2542	Europe/Andorra	1993-12-23
+3040331	Gargantillar	Gargantillar		42.5	1.65	A	ADMD	AD		00				0		2542	Europe/Andorra	1993-12-23
+3040332	Roc de la Garganta	Roc de la Garganta		42.55	1.6	T	RK	AD		00				0		2210	Europe/Andorra	1993-12-23
+3040333	Pas dels Gargalls	Pas dels Gargalls		42.6	1.68333	T	PASS	AD		00				0		2089	Europe/Andorra	1993-12-23
+3040334	Bosc de la Gargallosa	Bosc de la Gargallosa		42.56667	1.51667	V	FRST	AD		00				0		1500	Europe/Andorra	1993-12-23
+3040335	Torrent del Gargallet	Torrent del Gargallet		42.45	1.53333	H	STM	AD		00				0		1859	Europe/Andorra	1993-12-23
+3040336	Font del Gargallet	Font del Gargallet		42.45	1.53333	H	SPNG	AD		00				0		1859	Europe/Andorra	1993-12-23
+3040337	Clotada del Gargallet	Clotada del Gargallet		42.45	1.55	H	RVN	AD		00				0		2457	Europe/Andorra	1993-12-23
+3040338	Solana de Galliner	Solana de Galliner		42.56667	1.46667	T	SLP	AD		00				0		1673	Europe/Andorra	1993-12-23
+3040339	Riu de Galliner	Riu de Galliner		42.56667	1.48333	H	STM	AD		00				0		1508	Europe/Andorra	1993-12-23
+3040340	Galliner	Galliner		42.56667	1.46667	A	ADMD	AD		00				0		1673	Europe/Andorra	1993-12-23
+3040341	Planell de la Gallina	Planell de la Gallina		42.43333	1.5	T	UPLD	AD		00				0		1804	Europe/Andorra	1993-12-23
+3040342	Coll de la Gallina	Coll de la Gallina		42.46667	1.45	T	PASS	AD		00				0		1562	Europe/Andorra	1993-12-23
+3040343	Canal dels Gais	Canal dels Gais		42.48333	1.55	H	STM	AD		00				0		2233	Europe/Andorra	1993-12-23
+3040344	Borda del Gabriel	Borda del Gabriel		42.56667	1.58333	S	HUT	AD		00				0		1919	Europe/Andorra	1993-12-23
+3040345	Canal de la Fusta	Canal de la Fusta		42.55	1.55	H	RVN	AD		00				0		2097	Europe/Andorra	1993-12-23
+3040346	Font Freda	Font Freda		42.63333	1.56667	H	SPNG	AD		00				0		2394	Europe/Andorra	1993-12-23
+3040347	Font Freda	Font Freda		42.56667	1.46667	H	SPNG	AD		00				0		1673	Europe/Andorra	1993-12-23
+3040348	Font Freda	Font Freda		42.45	1.5	H	SPNG	AD		00				0		1614	Europe/Andorra	1993-12-23
+3040349	Font Fred	Font Fred		42.48333	1.6	H	SPNG	AD		00				0		2250	Europe/Andorra	1993-12-23
+3040350	Francolí	Francoli		42.48333	1.43333	A	ADMD	AD		00				0		1938	Europe/Andorra	1993-12-23
+3040351	Obaga Fosca	Obaga Fosca		42.48333	1.43333	T	SLP	AD		00				0		1938	Europe/Andorra	1993-12-23
+3040352	Collada Fosca	Collada Fosca		42.43333	1.5	T	SPUR	AD		00				0		1804	Europe/Andorra	1993-12-23
+3040353	Canal Fosca	Canal Fosca		42.6	1.53333	H	STM	AD		00				0		1695	Europe/Andorra	1993-12-23
+3040354	Canal Fosca	Canal Fosca		42.5	1.56667	H	STM	AD		00				0		1776	Europe/Andorra	1993-12-23
+3040355	Bosc Fosc	Bosc Fosc		42.56667	1.66667	V	FRST	AD		00				0		1938	Europe/Andorra	1993-12-23
+3040356	Pleta del Forquilló	Pleta del Forquillo		42.61667	1.7	L	GRAZ	AD		00				0		2285	Europe/Andorra	1993-12-23
+3040357	Collet de Forns	Collet de Forns		42.48333	1.48333	T	SPUR	AD		00				0		981	Europe/Andorra	1993-12-23
+3040358	Canals de la Forniga	Canals de la Forniga		42.5	1.45	H	STM	AD		00				0		1840	Europe/Andorra	1993-12-23
+3040359	Prat del Fornet	Prat del Fornet		42.55	1.61667	L	GRAZ	AD		00				0		2206	Europe/Andorra	1993-12-23
+3040360	Font del Fornell	Font del Fornell		42.45	1.5	H	SPNG	AD		00				0		1614	Europe/Andorra	1993-12-23
+3040361	Canal del Forn de la Calç	Canal del Forn de la Calc		42.55	1.55	H	STM	AD		00				0		2097	Europe/Andorra	1993-12-23
+3040362	Forn de Cals	Forn de Cals		42.56667	1.6	L	LCTY	AD		00				0		1655	Europe/Andorra	1993-12-23
+3040363	Turó del Forn	Turo del Forn		42.63333	1.58333	T	PK	AD		00				0		2470	Europe/Andorra	1993-12-23
+3040364	Torrent del Forn	Torrent del Forn		42.5	1.51667	H	STM	AD		00				0		1410	Europe/Andorra	1993-12-23
+3040365	Serrat del Forn	Serrat del Forn		42.55	1.51667	T	SPUR	AD		00				0		1397	Europe/Andorra	1993-12-23
+3040366	Roca del Forn	Roca del Forn		42.55	1.61667	T	RK	AD		00				0		2206	Europe/Andorra	1993-12-23
+3040367	Riu del Forn	Riu del Forn		42.55	1.6	H	STM	AD		00				0		2210	Europe/Andorra	1993-12-23
+3040368	Portella del Forn	Portella del Forn		42.63333	1.58333	T	PASS	AD		00				0		2470	Europe/Andorra	1993-12-23
+3040369	Planells del Forn	Planells del Forn		42.55	1.6	T	UPLD	AD		00				0		2210	Europe/Andorra	1993-12-23
+3040370	Obaga del Forn	Obaga del Forn		42.48333	1.43333	T	SLP	AD		00				0		1938	Europe/Andorra	1993-12-23
+3040371	Clots del Forn	Clots del Forn		42.63333	1.58333	H	RVN	AD		00				0		2470	Europe/Andorra	1993-12-23
+3040372	Carretera del Forn	Carretera del Forn		42.55	1.58333	R	RD	AD		00				0		1499	Europe/Andorra	1993-12-23
+3040373	Carrerada del Forn	Carrerada del Forn		42.56667	1.63333	R	TRL	AD		00				0		2016	Europe/Andorra	1993-12-23
+3040374	Canal del Forn	Canal del Forn		42.56667	1.51667	H	STM	AD		00				0		1500	Europe/Andorra	1993-12-23
+3040375	Camí del Forn	Cami del Forn		42.55	1.58333	R	TRL	AD		00				0		1499	Europe/Andorra	1993-12-23
+3040376	Estanys Forcats	Estanys Forcats		42.6	1.45	H	LKS	AD		00				0		2174	Europe/Andorra	1993-12-23
+3040377	Torrent Forcat	Torrent Forcat		42.45	1.51667	H	STM	AD		00				0		1790	Europe/Andorra	1993-12-23
+3040378	Estany Forcat	Estany Forcat		42.49439	1.63825	H	LK	AD		00				0		2538	Europe/Andorra	2011-04-19
+3040379	Estany Forcat	Estany Forcat		42.5	1.63333	H	LK	AD		00				0		2545	Europe/Andorra	1993-12-23
+3040380	Forats de l’Óssa	Forats de l'Ossa		42.61667	1.53333	L	LCTY	AD		00				0		1609	Europe/Andorra	1993-12-23
+3040381	Forat Fosc	Forat Fosc		42.55	1.56667	L	LCTY	AD		00				0		1828	Europe/Andorra	1993-12-23
+3040382	Riu de Forat de Rius	Riu de Forat de Rius		42.58333	1.63333	H	STM	AD		00				0		1722	Europe/Andorra	1993-12-23
+3040383	Collada del Forat de Malhiverns	Collada del Forat de Malhiverns		42.6	1.43333	T	PASS	AD		00				0		2667	Europe/Andorra	1993-12-23
+3040384	Cresta del Forat dels Malhiverns	Cresta del Forat dels Malhiverns	Cresta del Forat dels Malhiverns	42.6	1.43333	T	RDGE	AD		00				0		2667	Europe/Andorra	2011-11-05
+3040385	Forat dels Malhiverns	Forat dels Malhiverns		42.6	1.45	L	LCTY	AD		00				0		2174	Europe/Andorra	1993-12-23
+3040386	Forat dels Clots de Massat	Forat dels Clots de Massat		42.55	1.7	L	LCTY	AD		00				0		2358	Europe/Andorra	1993-12-23
+3040387	Forat d’Arau	Forat d'Arau		42.56667	1.48333	L	LCTY	AD		00				0		1508	Europe/Andorra	1993-12-23
+3040388	Coma del Forat	Coma del Forat		42.61667	1.48333	H	STMH	AD		00				0		2470	Europe/Andorra	1993-12-23
+3040389	Font de Fontverd	Font de Fontverd		42.5	1.6	H	SPNG	AD		00				0		2416	Europe/Andorra	1993-12-23
+3040390	Fontverd	Fontverd		42.48333	1.6	S	RUIN	AD		00				0		2250	Europe/Andorra	1993-12-23
+3040391	Fontverd	Fontverd		42.5	1.6	A	ADMD	AD		00				0		2416	Europe/Andorra	1993-12-23
+3040392	Riu de les Fonts de la Tosa	Riu de les Fonts de la Tosa		42.6	1.68333	H	STM	AD		00				0		2089	Europe/Andorra	1993-12-23
+3040393	Tosa de les Fonts	Tosa de les Fonts		42.55	1.65	T	UPLD	AD		00				0		2432	Europe/Andorra	1993-12-23
+3040394	Pic de les Fonts	Pic de les Fonts		42.6	1.6	T	PK	AD		00				0		2143	Europe/Andorra	1993-12-23
+3040395	Pic de les Fonts	Pic de les Fonts		42.6	1.48333	T	PK	AD		00				0		2441	Europe/Andorra	1993-12-23
+3040396	Estany de les Fonts	Estany de les Fonts		42.51667	1.66667	H	LK	AD		00				0		2410	Europe/Andorra	1993-12-23
+3040397	Comella de les Fonts	Comella de les Fonts		42.45	1.46667	H	STM	AD		00				0		935	Europe/Andorra	1993-12-23
+3040398	Clots de les Fonts	Clots de les Fonts		42.58333	1.68333	H	RVN	AD		00				0		2294	Europe/Andorra	1993-12-23
+3040399	Clot de les Fonts	Clot de les Fonts		42.55	1.65	H	RVN	AD		00				0		2432	Europe/Andorra	1993-12-23
+3040400	Clot de les Fonts	Clot de les Fonts		42.46667	1.45	H	RVN	AD		00				0		1562	Europe/Andorra	1993-12-23
+3040401	Clotada de les Fonts	Clotada de les Fonts		42.6	1.48333	T	SLP	AD		00				0		2441	Europe/Andorra	1993-12-23
+3040402	Canal de les Fonts	Canal de les Fonts		42.61667	1.51667	H	STM	AD		00				0		1716	Europe/Andorra	1993-12-23
+3040403	Bosc de les Fonts	Bosc de les Fonts		42.56667	1.6	V	FRST	AD		00				0		1655	Europe/Andorra	1993-12-23
+3040404	Aspre de les Fonts	Aspre de les Fonts		42.6	1.48333	V	VINS	AD		00				0		2441	Europe/Andorra	1993-12-23
+3040405	Bosc de la Font Roja	Bosc de la Font Roja		42.55	1.45	V	FRST	AD		00				0		1788	Europe/Andorra	1993-12-23
+3040406	Collet de Font Podrida	Collet de Font Podrida		42.58333	1.46667	T	PK	AD		00				0		1643	Europe/Andorra	1993-12-23
+3040407	Canal de la Font Llarga	Canal de la Font Llarga		42.6	1.65	H	STM	AD		00				0		2131	Europe/Andorra	1993-12-23
+3040408	Costa de Font Freda	Costa de Font Freda		42.63333	1.56667	T	SLP	AD		00				0		2394	Europe/Andorra	1993-12-23
+3040409	Font de Fontduí	Font de Fontdui		42.56667	1.68333	H	SPNG	AD		00				0		2340	Europe/Andorra	1993-12-23
+3040410	Obaga de la Font dels Pets	Obaga de la Font dels Pets		42.6	1.48333	T	SLP	AD		00				0		2441	Europe/Andorra	1993-12-23
+3040411	Torrent de la Font dels Pals	Torrent de la Font dels Pals		42.45	1.51667	H	STM	AD		00				0		1790	Europe/Andorra	1993-12-23
+3040412	Font del Solà	Font del Sola		42.58333	1.66667	H	STM	AD		00				0		2159	Europe/Andorra	1993-12-23
+3040413	Costa de la Font dels Miquelets	Costa de la Font dels Miquelets		42.58333	1.43333	T	SLP	AD		00				0		2412	Europe/Andorra	1993-12-23
+3040414	Font dels Comellassos	Font dels Comellassos		42.6	1.68333	H	STM	AD		00				0		2089	Europe/Andorra	1993-12-23
+3040415	Bosc de la Font del Pi	Bosc de la Font del Pi		42.58333	1.53333	V	FRST	AD		00				0		1924	Europe/Andorra	1993-12-23
+3040416	Bosc de la Font del Pascol	Bosc de la Font del Pascol		42.53333	1.55	V	FRST	AD		00				0		1344	Europe/Andorra	1993-12-23
+3040417	Serrat de la Font del Mallol	Serrat de la Font del Mallol		42.55	1.55	T	SPUR	AD		00				0		2097	Europe/Andorra	1993-12-23
+3040418	Bosc de la Font del Mallol	Bosc de la Font del Mallol		42.55	1.55	V	FRST	AD		00				0		2097	Europe/Andorra	1993-12-23
+3040419	Canal de la Font del Llop	Canal de la Font del Llop		42.55	1.46667	H	STM	AD		00				0		1585	Europe/Andorra	1993-12-23
+3040420	Bosc de la Font del Gripal	Bosc de la Font del Gripal		42.51667	1.5	V	FRST	AD		00				0		1688	Europe/Andorra	1993-12-23
+3040421	Canal de la Font del Cuc	Canal de la Font del Cuc		42.48333	1.51667	H	STM	AD		00				0		2061	Europe/Andorra	1993-12-23
+3040422	Canal de la Font del Boix	Canal de la Font del Boix		42.55	1.48333	H	STM	AD		00				0		1548	Europe/Andorra	1993-12-23
+3040423	Bosc de la Font del Bisbe	Bosc de la Font del Bisbe		42.55	1.46667	V	FRST	AD		00				0		1585	Europe/Andorra	1993-12-23
+3040424	Barranc de la Font de la Pauca	Barranc de la Font de la Pauca		42.56667	1.58333	H	STM	AD		00				0		1919	Europe/Andorra	1993-12-23
+3040425	Canal de la Font de l’Angleveta	Canal de la Font de l'Angleveta		42.53333	1.5	H	STM	AD		00				0		1357	Europe/Andorra	1993-12-23
+3040426	Planell de la Font de l’Altar	Planell de la Font de l'Altar		42.55	1.41667	T	UPLD	AD		00				0		2105	Europe/Andorra	1993-12-23
+3040427	Canal de la Font de la Gallina	Canal de la Font de la Gallina		42.48333	1.46667	H	STM	AD		00				0		1148	Europe/Andorra	1993-12-23
+3040428	Oratori de la Font de Joans	Oratori de la Font de Joans		42.48333	1.48333	S	AMTH	AD		00				0		981	Europe/Andorra	1993-12-23
+3040429	Basers de la Font de Joans	Basers de la Font de Joans		42.48333	1.48333	T	CLF	AD		00				0		981	Europe/Andorra	1993-12-23
+3040430	Canal de la Font de Gambada	Canal de la Font de Gambada		42.56667	1.5	H	STM	AD		00				0		1636	Europe/Andorra	1993-12-23
+3040431	Fontauzina	Fontauzina		42.58333	1.63333	T	SLP	AD		00				0		1722	Europe/Andorra	1993-12-23
+3040432	Camí de Fontargent	Cami de Fontargent		42.61667	1.71667	R	TRL	AD		00				0		2352	Europe/Andorra	1993-12-23
+3040433	Barranc de la Font Antiga	Barranc de la Font Antiga		42.55	1.48333	H	STM	AD		00				0		1548	Europe/Andorra	1993-12-23
+3040434	Canal de les Fontanelles	Canal de les Fontanelles		42.45	1.48333	H	STM	AD		00				0		1111	Europe/Andorra	1993-12-23
+3040435	Pont de Fontaneda	Pont de Fontaneda		42.46667	1.48333	S	BDG	AD		00				0		1134	Europe/Andorra	1993-12-23
+3040436	Boscarró de Fontaneda	Boscarro de Fontaneda		42.45	1.48333	V	FRST	AD		00				0		1111	Europe/Andorra	1993-12-23
+3040437	Fontaneda	Fontaneda		42.45432	1.46402	P	PPL	AD		06				0		1253	Europe/Andorra	2011-04-19
+3040438	Fontanals del Pui	Fontanals del Pui		42.46667	1.48333	H	STM	AD		00				0		1134	Europe/Andorra	1993-12-23
+3040439	Bosc dels Fontanals	Bosc dels Fontanals		42.55	1.58333	V	FRST	AD		00				0		1499	Europe/Andorra	1993-12-23
+3040440	Font del Fontanal	Font del Fontanal		42.46667	1.5	H	SPNG	AD		00				0		1383	Europe/Andorra	1993-12-23
+3040441	Canal del Fontanal	Canal del Fontanal		42.58333	1.65	H	RVN	AD		00				0		1767	Europe/Andorra	1993-12-23
+3040442	Riu de Font Amagada	Riu de Font Amagada		42.53333	1.53333	H	STM	AD		00				0		1521	Europe/Andorra	1993-12-23
+3040443	Planell de la Font	Planell de la Font		42.56667	1.66667	T	UPLD	AD		00				0		1938	Europe/Andorra	1993-12-23
+3040444	Costa de la Font	Costa de la Font		42.53333	1.51667	T	SLP	AD		00				0		1361	Europe/Andorra	1993-12-23
+3040445	Clot de la Font	Clot de la Font		42.6	1.66667	H	RVN	AD		00				0		1858	Europe/Andorra	1993-12-23
+3040446	Canal de la Font	Canal de la Font		42.58333	1.48333	H	STM	AD		00				0		1809	Europe/Andorra	1993-12-23
+3040447	Clots Fondos	Clots Fondos		42.55	1.61667	H	RVN	AD		00				0		2206	Europe/Andorra	1993-12-23
+3040448	Collada Fonda	Collada Fonda	Collada Fonda	42.46667	1.63333	T	PASS	AD		00				0		2619	Europe/Andorra	2011-11-05
+3040449	Canal Fonda	Canal Fonda		42.53333	1.61667	H	STM	AD		00				0		2237	Europe/Andorra	1993-12-23
+3040450	Cortal del Folc	Cortal del Folc		42.45	1.5	S	CRRL	AD		00				0		1614	Europe/Andorra	1993-12-23
+3040451	Planell del Fogal	Planell del Fogal		42.63333	1.56667	T	UPLD	AD		00				0		2394	Europe/Andorra	1993-12-23
+3040452	Planell de les Flores	Planell de les Flores		42.61667	1.5	T	UPLD	AD		00				0		2390	Europe/Andorra	1993-12-23
+3040453	Canal de les Flamies	Canal de les Flamies		42.58333	1.61667	H	RVN	AD		00				0		1707	Europe/Andorra	1993-12-23
+3040454	Roc del Fiter	Roc del Fiter		42.45	1.51667	T	CLF	AD		00				0		1790	Europe/Andorra	1993-12-23
+3040455	Borda del Fiter	Borda del Fiter		42.58333	1.61667	S	HUT	AD		00				0		1707	Europe/Andorra	1993-12-23
+3040456	Canal de la Fita	Canal de la Fita		42.53333	1.6	H	STM	AD		00				0		1888	Europe/Andorra	1993-12-23
+3040457	Bosc de la Fita	Bosc de la Fita		42.56667	1.53333	V	FRST	AD		00				0		1669	Europe/Andorra	1993-12-23
+3040458	Coll de Finestres	Coll de Finestres		42.43333	1.55	T	SPUR	AD		00				0		2178	Europe/Andorra	1993-12-23
+3040459	Coll de la Finestra	Coll de la Finestra		42.5	1.53333	T	SPUR	AD		00				0		1574	Europe/Andorra	1993-12-23
+3040460	Bosc de la Finestra	Bosc de la Finestra		42.55	1.46667	V	FRST	AD		00				0		1585	Europe/Andorra	1993-12-23
+3040461	Canal de les Fijoles	Canal de les Fijoles		42.58333	1.48333	H	RVN	AD		00				0		1809	Europe/Andorra	1993-12-23
+3040462	Canal de Fhasa	Canal de Fhasa		42.51667	1.56667	H	CNL	AD		00				0		1759	Europe/Andorra	1993-12-23
+3040463	Font de Ferrús	Font de Ferrus		42.51667	1.51667	H	SPNG	AD		00				0		1265	Europe/Andorra	1993-12-23
+3040464	Font de Ferro del Planell Gran	Font de Ferro del Planell Gran		42.53333	1.6	H	SPNG	AD		00				0		1888	Europe/Andorra	1993-12-23
+3040465	Font de Ferro	Font de Ferro		42.58333	1.58333	H	SPNG	AD		00				0		1993	Europe/Andorra	1993-12-23
+3040466	Font de Ferro	Font de Ferro		42.46667	1.48333	H	SPNG	AD		00				0		1134	Europe/Andorra	1993-12-23
+3040467	Solana de Ferreroles	Solana de Ferreroles		42.6	1.56667	T	SLP	AD		00				0		2513	Europe/Andorra	1993-12-23
+3040468	Riu de Ferreroles	Riu de Ferreroles		42.6	1.53333	H	STM	AD		00				0		1695	Europe/Andorra	1993-12-23
+3040469	Planells de Ferreroles	Planells de Ferreroles		42.6	1.55	T	UPLD	AD		00				0		2298	Europe/Andorra	1993-12-23
+3040470	Collada de Ferreroles	Collada de Ferreroles		42.61667	1.56667	T	PASS	AD		00				0		2228	Europe/Andorra	1993-12-23
+3040471	Clots de Ferreroles	Clots de Ferreroles		42.6	1.56667	H	RVN	AD		00				0		2513	Europe/Andorra	1993-12-23
+3040472	Pont de Ferreres	Pont de Ferreres		42.6	1.53333	S	BDG	AD		00				0		1695	Europe/Andorra	1993-12-23
+3040473	Font del Feritxet	Font del Feritxet		42.51667	1.6	H	SPNG	AD		00				0		2085	Europe/Andorra	1993-12-23
+3040474	Feritxet	Feritxet		42.51667	1.6	A	ADMD	AD		00				0		2085	Europe/Andorra	1993-12-23
+3040475	Font del Fenoll	Font del Fenoll		42.58333	1.46667	H	SPNG	AD		00				0		1643	Europe/Andorra	1993-12-23
+3040476	Barranc del Fenetau	Barranc del Fenetau		42.6	1.66667	H	STM	AD		00				0		1858	Europe/Andorra	1993-12-23
+3040477	Bosc dels Feners	Bosc dels Feners		42.43333	1.5	V	FRST	AD		00				0		1804	Europe/Andorra	1993-12-23
+3040478	Bordes dels Fenerols	Bordes dels Fenerols		42.53333	1.5	S	HUTS	AD		00				0		1357	Europe/Andorra	1993-12-23
+3040479	Fener Llong	Fener Llong		42.55	1.55	L	LCTY	AD		00				0		2097	Europe/Andorra	1993-12-23
+3040480	Canal de Fener de Cussols	Canal de Fener de Cussols		42.53333	1.51667	H	STM	AD		00				0		1361	Europe/Andorra	1993-12-23
+3040481	Fener de Comadejó	Fener de Comadejo		42.5	1.48333	L	LCTY	AD		00				0		1316	Europe/Andorra	1993-12-23
+3040482	Canal del Fener Blanc	Canal del Fener Blanc		42.48333	1.48333	H	STM	AD		00				0		981	Europe/Andorra	1993-12-23
+3040483	Torrent dels Fenerals	Torrent dels Fenerals		42.5	1.45	H	STM	AD		00				0		1840	Europe/Andorra	1993-12-23
+3040484	Obagues dels Fenerals	Obagues dels Fenerals		42.5	1.45	T	SLP	AD		00				0		1840	Europe/Andorra	1993-12-23
+3040485	Bosc de les Fenemores	Bosc de les Fenemores		42.53333	1.48333	V	FRST	AD		00				0		1677	Europe/Andorra	1993-12-23
+3040486	Borda del Fenemars	Borda del Fenemars		42.58333	1.63333	S	HUT	AD		00				0		1722	Europe/Andorra	1993-12-23
+3040487	Barraca de Fembra Morta	Barraca de Fembra Morta		42.56667	1.71667	S	HUT	AD		00				0		2219	Europe/Andorra	1993-12-23
+3040488	Bosc del Felegrill	Bosc del Felegrill		42.53333	1.53333	V	FRST	AD		00				0		1521	Europe/Andorra	1993-12-23
+3040489	Bosc de les Feixes	Bosc de les Feixes		42.55	1.43333	V	FRST	AD		00				0		1949	Europe/Andorra	1993-12-23
+3040490	Feixar de Setut	Feixar de Setut		42.46667	1.63333	L	LCTY	AD		00				0		2619	Europe/Andorra	1993-12-23
+3040491	Feixar del Baladre	Feixar del Baladre		42.65	1.55	L	LCTY	AD		00				0		2181	Europe/Andorra	1993-12-23
+3040492	Pic del Feixar	Pic del Feixar		42.46667	1.63333	T	PK	AD		00				0		2619	Europe/Andorra	1993-12-23
+3040493	Font del Feixar	Font del Feixar		42.46667	1.63333	H	SPNG	AD		00				0		2619	Europe/Andorra	1993-12-23
+3040494	Feixants de Xixerella	Feixants de Xixerella		42.55	1.48333	L	LCTY	AD		00				0		1548	Europe/Andorra	1993-12-23
+3040495	Feixa de l’Escobar	Feixa de l'Escobar		42.43333	1.5	L	LCTY	AD		00				0		1804	Europe/Andorra	1993-12-23
+3040496	Clots de la Febrerrussa	Clots de la Febrerrussa		42.46667	1.55	H	RVN	AD		00				0		2341	Europe/Andorra	1993-12-23
+3040497	Canal del Favar	Canal del Favar		42.51667	1.53333	H	STM	AD		00				0		1460	Europe/Andorra	1993-12-23
+3040498	Solà de Faucellers	Sola de Faucellers		42.45	1.5	T	SLP	AD		00				0		1614	Europe/Andorra	1993-12-23
+3040499	Pont de Faucellers	Pont de Faucellers		42.45	1.5	S	BDG	AD		00				0		1614	Europe/Andorra	1993-12-23
+3040500	Faucellers	Faucellers		42.45	1.5	L	LCTY	AD		00				0		1614	Europe/Andorra	1993-12-23
+3040501	Serrat de la Farga	Serrat de la Farga		42.45	1.53333	T	RDGE	AD		00				0		1859	Europe/Andorra	1993-12-23
+3040502	Pont de la Farga	Pont de la Farga		42.61667	1.53333	S	BDG	AD		00				0		1609	Europe/Andorra	1993-12-23
+3040503	Barraca de la Farga	Barraca de la Farga		42.5	1.6	S	HUT	AD		00				0		2416	Europe/Andorra	1993-12-23
+3040504	Roc del Far	Roc del Far		42.43333	1.5	T	RK	AD		00				0		1804	Europe/Andorra	1993-12-23
+3040505	Plana del Far	Plana del Far		42.48333	1.41667	T	SLP	AD		00				0		1920	Europe/Andorra	1993-12-23
+3040506	Fangots de Moretó	Fangots de Moreto		42.55	1.68333	L	LCTY	AD		00				0		2254	Europe/Andorra	1993-12-23
+3040507	Fangots dels Maians	Fangots dels Maians		42.55	1.61667	L	LCTY	AD		00				0		2206	Europe/Andorra	1993-12-23
+3040508	Fangot Gran	Fangot Gran		42.53333	1.63333	L	LCTY	AD		00				0		2360	Europe/Andorra	1993-12-23
+3040509	Canya de les Falgueres	Canya de les Falgueres		42.45	1.46667	S	CAVE	AD		00				0		935	Europe/Andorra	1993-12-23
+3040510	Falconeres	Falconeres		42.55	1.7	L	LCTY	AD		00				0		2358	Europe/Andorra	1993-12-23
+3040511	Serra de Falcobí	Serra de Falcobi		42.63333	1.55	T	MT	AD		00				0		2053	Europe/Andorra	1993-12-23
+3040512	Canya dels Eucassers	Canya dels Eucassers		42.55	1.61667	S	CAVE	AD		00				0		2206	Europe/Andorra	1993-12-23
+3040513	Cabana de l' Eucasser	Cabana de l' Eucasser		42.63086	1.48341	S	HUT	AD		07				0		2111	Europe/Andorra	2007-03-04
+3040514	Cabana de l’ Eucasser	Cabana de l' Eucasser		42.61667	1.56667	S	HUT	AD		00				0		2228	Europe/Andorra	1993-12-23
+3040515	Cabana de l’ Eucasser	Cabana de l' Eucasser		42.58333	1.61667	S	HUT	AD		00				0		1707	Europe/Andorra	1993-12-23
+3040516	Pala Estreta	Pala Estreta		42.55	1.7	T	SLP	AD		00				0		2358	Europe/Andorra	1993-12-23
+3040517	Torrent Estret	Torrent Estret		42.53333	1.56667	H	STM	AD		00				0		1418	Europe/Andorra	1993-12-23
+3040518	Cortal de Estevet	Cortal de Estevet		42.5	1.53333	S	CRRL	AD		00				0		1574	Europe/Andorra	1993-12-23
+3040519	Collada dels Estanys Forcats	Collada dels Estanys Forcats	Collada dels Estanys Forcats	42.6	1.45	T	PK	AD		00				0		2174	Europe/Andorra	2011-11-05
+3040520	Clots de l’ Estany Segon	Clots de l' Estany Segon		42.61667	1.73333	H	RVN	AD		00				0		2508	Europe/Andorra	1993-12-23
+3040521	Estanys de Tristaina	Estanys de Tristaina		42.64217	1.48615	H	LKS	AD		07				0		2530	Europe/Andorra	2007-04-29
+3040522	Estanys del Pessons	Estanys del Pessons		42.51667	1.66667	L	LCTY	AD		00				0		2410	Europe/Andorra	1993-12-23
+3040523	Estanys de l’Obac	Estanys de l'Obac		42.51667	1.66667	L	LCTY	AD		00				0		2410	Europe/Andorra	1993-12-23
+3040524	Estanys de la Solana	Estanys de la Solana		42.53333	1.66667	L	LCTY	AD		00				0		2489	Europe/Andorra	1993-12-23
+3040525	Estanys de Juclar	Estanys de Juclar		42.61667	1.71667	L	LCTY	AD		00				0		2352	Europe/Andorra	1993-12-23
+3040526	Serra dels Estanys	Serra dels Estanys		42.58333	1.58333	T	RDGE	AD		00				0		1993	Europe/Andorra	1993-12-23
+3040527	Riu dels Estanys	Riu dels Estanys		42.6	1.61667	H	STM	AD		00				0		2271	Europe/Andorra	1993-12-23
+3040528	Collada dels Estanys	Collada dels Estanys		42.58333	1.58333	T	PASS	AD		00				0		1993	Europe/Andorra	1993-12-23
+3040529	Camí dels Estanys	Cami dels Estanys		42.48333	1.65	R	TRL	AD		00				0		2658	Europe/Andorra	1993-12-23
+3040530	Cabana dels Estanys	Cabana dels Estanys		42.48333	1.65	S	HUT	AD		00				0		2658	Europe/Andorra	1993-12-23
+3040531	Estanyons de Banyell	Estanyons de Banyell		42.65	1.56667	L	LCTY	AD		00				0		2471	Europe/Andorra	1993-12-23
+3040532	Pic dels Estanyons	Pic dels Estanyons	Pic dels Estanyons,Toseta de la Colilla,Tosseta de la Caulla,Tosseta de la Caülla	42.46667	1.61667	T	PK	AD		00				0		2448	Europe/Andorra	2011-11-05
+3040533	Estanys dels Estanyons	Estanys dels Estanyons		42.46667	1.61667	H	LKS	AD		00				0		2448	Europe/Andorra	1993-12-23
+3040534	Canals Tancades dels Estanyons	Canals Tancades dels Estanyons		42.46667	1.63333	H	RVN	AD		00				0		2619	Europe/Andorra	1993-12-23
+3040535	Bosc dels Estanyons	Bosc dels Estanyons		42.48333	1.63333	V	FRST	AD		00				0		2296	Europe/Andorra	1993-12-23
+3040536	Serra de l’ Estanyó	Serra de l' Estanyo		42.6	1.58333	T	MT	AD		00				0		2461	Europe/Andorra	1993-12-23
+3040537	Saleres de l’ Estanyó	Saleres de l' Estanyo		42.61667	1.56667	L	SALT	AD		00				0		2228	Europe/Andorra	1993-12-23
+3040538	Riu de l’ Estanyó	Riu de l' Estanyo		42.61667	1.56667	H	STM	AD		00				0		2228	Europe/Andorra	1993-12-23
+3040539	Pic de l’ Estanyó	Pic de l' Estanyo	Montagne de l' Estanyo,Montagne de l’ Estanyó,Pic de l' Estanyo,Pic de l’ Estanyó	42.6088	1.59235	T	PK	AD		00				0		2709	Europe/Andorra	2011-11-05
+3040540	Estret de l’ Estanyó	Estret de l' Estanyo		42.61667	1.56667	T	PASS	AD		00				0		2228	Europe/Andorra	1993-12-23
+3040541	Estany de l’ Estanyó	Estany de l' Estanyo		42.61667	1.58333	H	LK	AD		00				0		2374	Europe/Andorra	1993-12-23
+3040542	Clots de l’ Estanyó	Clots de l' Estanyo		42.61667	1.58333	H	STMH	AD		00				0		2374	Europe/Andorra	1993-12-23
+3040543	Canals de l’ Estanyó	Canals de l' Estanyo		42.6	1.58333	H	RVN	AD		00				0		2461	Europe/Andorra	1993-12-23
+3040544	Serrat de l’ Estany Negre	Serrat de l' Estany Negre		42.58333	1.43333	T	SPUR	AD		00				0		2412	Europe/Andorra	1993-12-23
+3040545	Rocs de l’ Estany Negre	Rocs de l' Estany Negre		42.58333	1.43333	T	RKS	AD		00				0		2412	Europe/Andorra	1993-12-23
+3040546	Basses de l’ Estany Negre	Basses de l' Estany Negre		42.58333	1.43333	H	LK	AD		00				0		2412	Europe/Andorra	1993-12-23
+3040547	Bony de l’ Estany Mort	Bony de l' Estany Mort		42.61667	1.61667	T	SPUR	AD		00				0		2352	Europe/Andorra	1993-12-23
+3040548	Roc de l’ Estany Moreno	Roc de l' Estany Moreno		42.51667	1.63333	T	CLF	AD		00				0		2379	Europe/Andorra	1993-12-23
+3040549	Pala de l’ Estany Gran	Pala de l' Estany Gran		42.6	1.58333	T	CLF	AD		00				0		2461	Europe/Andorra	1993-12-23
+3040550	Riu de l' Estany Esbalçat	Riu de l' Estany Esbalcat		42.63612	1.51736	H	STM	AD		07				0		2334	Europe/Andorra	2007-03-04
+3040551	Port de l’ Estany Esbalçat	Port de l' Estany Esbalcat		42.65	1.51667	T	PASS	AD		00				0		2546	Europe/Andorra	1993-12-23
+3040552	Costa de l’ Estany de Més Avall	Costa de l' Estany de Mes Avall		42.6	1.48333	T	SPUR	AD		00				0		2441	Europe/Andorra	1993-12-23
+3040553	Clots de l’ Estany de Més Avall	Clots de l' Estany de Mes Avall		42.6	1.48333	T	TAL	AD		00				0		2441	Europe/Andorra	1993-12-23
+3040554	Costa de l’ Estany de Més Amunt	Costa de l' Estany de Mes Amunt		42.61667	1.48333	T	SLP	AD		00				0		2470	Europe/Andorra	1993-12-23
+3040555	Costa de l’ Estany del Mig	Costa de l' Estany del Mig		42.65	1.48333	T	SLP	AD		00				0		2341	Europe/Andorra	1993-12-23
+3040556	Canals d’Amunt de l’ Estany del Mig	Canals d'Amunt de l' Estany del Mig		42.6	1.48333	H	RVN	AD		00				0		2441	Europe/Andorra	1993-12-23
+3040557	Riu de l’ Estany de l’Isla	Riu de l' Estany de l'Isla		42.61667	1.7	H	STM	AD		00				0		2285	Europe/Andorra	1993-12-23
+3040558	Canal de l’ Estany de l’Isla	Canal de l' Estany de l'Isla		42.61667	1.68333	H	RVN	AD		00				0		2406	Europe/Andorra	1993-12-23
+3040559	Solana de l’ Estany de l’Illa	Solana de l' Estany de l'Illa		42.5	1.65	T	SLP	AD		00				0		2542	Europe/Andorra	1993-12-23
+3040560	Baser de l’ Estany de les Truites	Baser de l' Estany de les Truites		42.56667	1.43333	T	CLF	AD		00				0		2402	Europe/Andorra	1993-12-23
+3040561	Turó de l’ Estany de la Nou	Turo de l' Estany de la Nou		42.46667	1.58333	T	SPUR	AD		00				0		2367	Europe/Andorra	1993-12-23
+3040562	Camí de l’ Estany de la Nou	Cami de l' Estany de la Nou		42.48333	1.58333	R	TRL	AD		00				0		2349	Europe/Andorra	1993-12-23
+3040563	Riu de l' Estany de Creussans	Riu de l' Estany de Creussans		42.63292	1.47976	H	STM	AD		07				0		2283	Europe/Andorra	2007-03-04
+3040564	Vial de l’ Estany Blau	Vial de l' Estany Blau		42.5	1.61667	R	RD	AD		00				0		2560	Europe/Andorra	1993-12-23
+3040565	Turo de l’ Estany Blau	Turo de l' Estany Blau		42.5	1.61667	T	PK	AD		00				0		2560	Europe/Andorra	1993-12-23
+3040566	Riu de l’ Estany Blau	Riu de l' Estany Blau		42.5	1.61667	H	STM	AD		00				0		2560	Europe/Andorra	1993-12-23
+3040567	Canals de l’ Estany Blau	Canals de l' Estany Blau		42.5	1.6	H	RVN	AD		00				0		2416	Europe/Andorra	1993-12-23
+3040568	Serrat de l’ Estany	Serrat de l' Estany		42.51667	1.56667	T	MT	AD		00				0		1759	Europe/Andorra	1993-12-23
+3040569	Riu de l’ Estany	Riu de l' Estany		42.58333	1.43333	H	STM	AD		00				0		2412	Europe/Andorra	1993-12-23
+3040570	Pla de l’ Estany	Pla de l' Estany		42.6	1.46667	T	UPLD	AD		00				0		2421	Europe/Andorra	1993-12-23
+3040571	Pleta de l’ Estall Serrer	Pleta de l' Estall Serrer		42.48333	1.61667	L	GRAZ	AD		00				0		2217	Europe/Andorra	1993-12-23
+3040572	Planells de l’ Estall Serrer	Planells de l' Estall Serrer		42.48333	1.61667	T	UPLD	AD		00				0		2217	Europe/Andorra	1993-12-23
+3040573	Canals de l’ Estall Serrer	Canals de l' Estall Serrer		42.48333	1.61667	H	RVN	AD		00				0		2217	Europe/Andorra	1993-12-23
+3040574	Bosc de l’ Estall Serrer	Bosc de l' Estall Serrer		42.48333	1.61667	V	FRST	AD		00				0		2217	Europe/Andorra	1993-12-23
+3040575	Estall Serrer	Estall Serrer		42.48333	1.61667	L	LCTY	AD		00				0		2217	Europe/Andorra	1993-12-23
+3040576	Estall Serrer	Estall Serrer		42.46667	1.61667	A	ADMD	AD		00				0		2448	Europe/Andorra	1993-12-23
+3040577	Roc de l’ Estall	Roc de l' Estall		42.5	1.58333	T	RK	AD		00				0		1888	Europe/Andorra	1993-12-23
+3040578	Planell de l’ Estall	Planell de l' Estall		42.55	1.55	T	UPLD	AD		00				0		2097	Europe/Andorra	1993-12-23
+3040579	Collada de l’ Estall	Collada de l' Estall		42.55	1.55	T	PASS	AD		00				0		2097	Europe/Andorra	1993-12-23
+3040580	Carretera de l’ Estall	Carretera de l' Estall		42.53333	1.53333	R	RD	AD		00				0		1521	Europe/Andorra	1993-12-23
+3040581	Borda de l’ Estall	Borda de l' Estall		42.55	1.55	S	HUT	AD		00				0		2097	Europe/Andorra	1993-12-23
+3040582	Pleta de l’ Estaleritx	Pleta de l' Estaleritx		42.61667	1.55	L	GRAZ	AD		00				0		2007	Europe/Andorra	1993-12-23
+3040583	Collada de l’ Estaleritx	Collada de l' Estaleritx		42.61667	1.55	T	SPUR	AD		00				0		2007	Europe/Andorra	1993-12-23
+3040584	Pont dels Esquirols	Pont dels Esquirols		42.56667	1.48333	S	BDG	AD		00				0		1508	Europe/Andorra	1993-12-23
+3040585	Roc de les Esquiroles	Roc de les Esquiroles		42.46667	1.5	T	RK	AD		00				0		1383	Europe/Andorra	1993-12-23
+3040586	Roc de les Esquiroles	Roc de les Esquiroles		42.45	1.48333	T	RK	AD		00				0		1111	Europe/Andorra	1993-12-23
+3040587	Canal de les Esquiroles	Canal de les Esquiroles		42.45	1.48333	H	STM	AD		00				0		1111	Europe/Andorra	1993-12-23
+3040588	Roc d’ Esquers	Roc d' Esquers		42.5	1.55	T	RK	AD		00				0		1566	Europe/Andorra	1993-12-23
+3040589	Roc de l’ Espluga	Roc de l' Espluga		42.46667	1.46667	T	RK	AD		00				0		1340	Europe/Andorra	1993-12-23
+3040590	Planell de l’ Espluga	Planell de l' Espluga		42.46667	1.46667	T	UPLD	AD		00				0		1340	Europe/Andorra	1993-12-23
+3040591	Tosa dels Espiolets	Tosa dels Espiolets		42.55	1.65	T	UPLD	AD		00				0		2432	Europe/Andorra	1993-12-23
+3040592	Espeluga	Espeluga		42.56667	1.43333	L	LCTY	AD		00				0		2402	Europe/Andorra	1993-12-23
+3040593	Espeluga	Espeluga		42.53333	1.55	A	ADMD	AD		00				0		1344	Europe/Andorra	1993-12-23
+3040594	Pont de l’ Espalmera	Pont de l' Espalmera		42.55	1.46667	S	BDG	AD		00				0		1585	Europe/Andorra	1993-12-23
+3040595	Riu de l’ Escobet	Riu de l' Escobet		42.46667	1.51667	H	STM	AD		00				0		1985	Europe/Andorra	1993-12-23
+3040596	Escobet	Escobet		42.46667	1.51667	L	LCTY	AD		00				0		1985	Europe/Andorra	1993-12-23
+3040597	Cylindre d’ Ascobes	Cylindre d' Ascobes	Cylindre d' Ascobes,Cylindre d’ Ascobes,Pic d' Escobes,Pic d’ Escobes	42.6	1.73333	T	PK	AD		00				0		2383	Europe/Andorra	2011-11-05
+3040598	Comella dels Esclops	Comella dels Esclops		42.43333	1.48333	H	STM	AD		00				0		1228	Europe/Andorra	1993-12-23
+3040599	Solà d’ Escàs	Sola d' Escas		42.55	1.5	T	SLP	AD		00				0		1292	Europe/Andorra	1993-12-23
+3040600	Camí d’ Escàs	Cami d' Escas		42.55	1.5	R	TRL	AD		00				0		1292	Europe/Andorra	1993-12-23
+3040601	Escàs	Escas		42.54643	1.50895	P	PPL	AD		04				0		1257	Europe/Andorra	2011-04-19
+3040602	Roc d’ Escalluquer	Roc d' Escalluquer		42.55	1.5	T	CLF	AD		00				0		1292	Europe/Andorra	1993-12-23
+3040603	Bosc d’ Escalluquer	Bosc d' Escalluquer		42.55	1.5	V	FRST	AD		00				0		1292	Europe/Andorra	1993-12-23
+3040604	Escalluquer	Escalluquer		42.55	1.5	A	ADMD	AD		00				0		1292	Europe/Andorra	1993-12-23
+3040605	Canal de l’ Escalella	Canal de l' Escalella		42.5	1.45	H	STM	AD		00				0		1840	Europe/Andorra	1993-12-23
+3040606	Vial de l’ Escala	Vial de l' Escala		42.48333	1.5	R	RD	AD		00				0		1631	Europe/Andorra	1993-12-23
+3040607	Estany Esbalçat	Estany Esbalcat		42.64002	1.51371	H	LK	AD		07				0		2130	Europe/Andorra	2007-03-04
+3040608	Obac d’ Erts	Obac d' Erts		42.56667	1.5	T	SLP	AD		00				0		1636	Europe/Andorra	1993-12-23
+3040609	Erts	Erts	Ercs,Ercz,Erez	42.56218	1.4968	P	PPL	AD	AD	04				0		1430	Europe/Andorra	2007-04-16
+3040610	Costa de les Eroles	Costa de les Eroles		42.56667	1.45	T	SLP	AD		00				0		2137	Europe/Andorra	1993-12-23
+3040611	Solana de l’ Era de Mitges	Solana de l' Era de Mitges		42.46667	1.45	T	SLP	AD		00				0		1562	Europe/Andorra	1993-12-23
+3040612	Refugi d’ Envalira	Refugi d' Envalira		42.53333	1.68333	S	RSRT	AD		00				0		2322	Europe/Andorra	1993-12-23
+3040613	Port d’ Envalira	Port d' Envalira	Port d' Envalira,Port d’ Envalira,Puerto d' Envalira,Puerto d’ Envalira	42.54041	1.71897	T	PASS	AD		00				0		2230	Europe/Andorra	2011-11-05
+3040615	Bordes d’ Envalira	Bordes d' Envalira	Bordas d' Envalira,Bordas d’ Envalira,Bordes d' Envalira,Bordes d’ Envalira	42.56667	1.68333	S	HUTS	AD		00				0		2340	Europe/Andorra	2011-11-05
+3040616	Envalira	Envalira		42.53333	1.7	A	ADMD	AD		00				0		2357	Europe/Andorra	1993-12-23
+3040617	Solà d’ Entremesaiqües	Sola d' Entremesaiques		42.50094	1.55771	T	SLP	AD		00				0		1621	Europe/Andorra	2011-04-19
+3040618	Pont d’ Entremesaigües	Pont d' Entremesaigues		42.5	1.56667	S	BDG	AD		00				0		1776	Europe/Andorra	1993-12-23
+3040619	Entremesaigües	Entremesaigues		42.49692	1.55577	L	LCTY	AD		00				0		1566	Europe/Andorra	2011-04-19
+3040620	Roca Entravessada	Roca Entravessada		42.5986	1.44241	T	SPUR	AD		00				0		2406	Europe/Andorra	2011-04-19
+3040621	Font de les Entrades	Font de les Entrades		42.56667	1.48333	H	SPNG	AD		00				0		1508	Europe/Andorra	1993-12-23
+3040622	Bosc de l’ Entrada	Bosc de l' Entrada		42.55	1.46667	V	FRST	AD		00				0		1585	Europe/Andorra	1993-12-23
+3040623	Camí d’ Entor	Cami d' Entor		42.58333	1.63333	R	TRL	AD		00				0		1722	Europe/Andorra	1993-12-23
+3040624	Bosc d’ Entor	Bosc d' Entor		42.58333	1.65	V	FRST	AD		00				0		1767	Europe/Andorra	1993-12-23
+3040625	Entor	Entor		42.6	1.65	A	ADMD	AD		00				0		2131	Europe/Andorra	1993-12-23
+3040626	Collada d’ Entinyola	Collada d' Entinyola		42.51667	1.65	T	PASS	AD		00				0		2633	Europe/Andorra	1993-12-23
+3040627	Clots d’ Entinyac	Clots d' Entinyac		42.58333	1.68333	H	STMH	AD		00				0		2294	Europe/Andorra	1993-12-23
+3040628	Tarteres d’ Entalàs	Tarteres d' Entalas		42.53333	1.63333	T	TAL	AD		00				0		2360	Europe/Andorra	1993-12-23
+3040629	Canals d’ Entalàs	Canals d' Entalas		42.53333	1.63333	H	RVN	AD		00				0		2360	Europe/Andorra	1993-12-23
+3040630	Bosc d’ En Som	Bosc d' En Som		42.56667	1.58333	V	FRST	AD		00				0		1919	Europe/Andorra	1993-12-23
+3040631	Serra de l’ Ensegur	Serra de l' Ensegur		42.58333	1.55	T	RDGE	AD		00				0		2357	Europe/Andorra	1993-12-23
+3040632	Riu de l’ Ensegur	Riu de l' Ensegur		42.6	1.53333	H	STM	AD		00				0		1695	Europe/Andorra	1993-12-23
+3040633	Obaga de l’ Ensegur	Obaga de l' Ensegur		42.58333	1.55	T	SLP	AD		00				0		2357	Europe/Andorra	1993-12-23
+3040634	Collada de l’ Ensegur	Collada de l' Ensegur		42.58333	1.53333	T	PASS	AD		00				0		1924	Europe/Andorra	1993-12-23
+3040635	Clot de l’ Ensegur	Clot de l' Ensegur		42.58333	1.55	H	RVN	AD		00				0		2357	Europe/Andorra	1993-12-23
+3040636	Camí de l’ Ensegur	Cami de l' Ensegur		42.58333	1.53333	R	TRL	AD		00				0		1924	Europe/Andorra	1993-12-23
+3040637	Bosc de l’ Ensegur	Bosc de l' Ensegur		42.6	1.55	V	FRST	AD		00				0		2298	Europe/Andorra	1993-12-23
+3040638	Bordes de l’ Ensegur	Bordes de l' Ensegur		42.58333	1.55	S	HUTS	AD		00				0		2357	Europe/Andorra	1993-12-23
+3040639	Aspres de l’ Ensegur	Aspres de l' Ensegur		42.58333	1.55	V	VINS	AD		00				0		2357	Europe/Andorra	1993-12-23
+3040640	Solana d’ Ensagents	Solana d' Ensagents		42.51667	1.63333	T	SLP	AD		00				0		2379	Europe/Andorra	1993-12-23
+3040641	Riu d’ Ensagents	Riu d' Ensagents		42.52752	1.6099	H	STM	AD		00				0		2101	Europe/Andorra	2011-04-19
+3040642	Obaga d’ Ensagents	Obaga d' Ensagents		42.51667	1.63333	T	SLP	AD		00				0		2379	Europe/Andorra	1993-12-23
+3040643	Estanys d’ Ensagents	Estanys d' Ensagents		42.52041	1.64793	H	LKS	AD		00				0		2627	Europe/Andorra	2011-04-19
+3040644	Ensagents	Ensagents		42.51667	1.65	A	ADMD	AD		00				0		2633	Europe/Andorra	1993-12-23
+3040645	Costa d’ Enradort	Costa d' Enradort		42.53333	1.66667	T	SLP	AD		00				0		2489	Europe/Andorra	1993-12-23
+3040646	Collada d’ Enradort	Collada d' Enradort		42.53333	1.66667	T	PASS	AD		00				0		2489	Europe/Andorra	1993-12-23
+3040647	Rec d’ Engordany	Rec d' Engordany		42.51667	1.53333	H	CNL	AD		00				0		1460	Europe/Andorra	1993-12-23
+3040648	Engordany	Engordany	Engordany	42.51115	1.54118	P	PPL	AD		08				0		1139	Europe/Andorra	2007-04-05
+3040649	Pla d’ Engolasters	Pla d' Engolasters		42.5	1.56667	T	UPLD	AD		00				0		1776	Europe/Andorra	1993-12-23
+3040650	Estany d'Engolasters	Estany d'Engolasters		42.51966	1.56772	H	LK	AD		07				0	1615	1759	Europe/Andorra	2007-04-05
+3040651	Carretera d’ Engolasters	Carretera d' Engolasters		42.51667	1.56667	R	RD	AD		00				0		1759	Europe/Andorra	1993-12-23
+3040652	Canal d’ Engolasters	Canal d' Engolasters		42.53333	1.6	H	CNL	AD		00				0		1888	Europe/Andorra	1993-12-23
+3040653	Engolasters	Engolasters		42.5	1.56667	A	ADMD	AD		00				0		1776	Europe/Andorra	1993-12-23
+3040654	Estany d’ Engaït	Estany d' Engait		42.51667	1.71667	H	LK	AD		00				0		2591	Europe/Andorra	1993-12-23
+3040655	Engaït	Engait		42.51667	1.71667	A	ADMD	AD		00				0		2591	Europe/Andorra	1993-12-23
+3040656	Serrat de l’ Enfreu	Serrat de l' Enfreu		42.56667	1.56667	T	RDGE	AD		00				0		2089	Europe/Andorra	1993-12-23
+3040657	Riu de l’ Enfreu	Riu de l' Enfreu		42.56667	1.55	H	STM	AD		00				0		1996	Europe/Andorra	1993-12-23
+3040658	Bosc de l’ Enfreu	Bosc de l' Enfreu		42.56667	1.55	V	FRST	AD		00				0		1996	Europe/Andorra	1993-12-23
+3040659	Borda d’ Endrieta	Borda d' Endrieta		42.55	1.58333	S	HUT	AD		00				0		1499	Europe/Andorra	1993-12-23
+3040660	Obaga d’ Encortesa	Obaga d' Encortesa		42.45	1.51667	T	SLP	AD		00				0		1790	Europe/Andorra	1993-12-23
+3040661	Carretera Encortesa	Carretera Encortesa		42.45	1.5	R	RD	AD		00				0		1614	Europe/Andorra	1993-12-23
+3040662	Encortesa	Encortesa		42.45	1.51667	L	LCTY	AD		00				0		1790	Europe/Andorra	1993-12-23
+3040663	Camí d’ Encodina	Cami d' Encodina		42.63333	1.53333	R	TRL	AD		00				0		2072	Europe/Andorra	1993-12-23
+3040664	Encodina	Encodina		42.63333	1.53333	L	LCTY	AD		00				0		2072	Europe/Andorra	1993-12-23
+3040665	Serra d’ Enclar	Serra d' Enclar		42.51408	1.48329	T	RDGE	AD		00				0		2069	Europe/Andorra	2011-04-19
+3040666	Riu d’ Enclar	Riu d' Enclar		42.49067	1.49562	H	STM	AD		00				0		1353	Europe/Andorra	2011-04-19
+3040667	Prat d’ Enclar	Prat d' Enclar		42.5	1.48333	L	GRAZ	AD		00				0		1316	Europe/Andorra	1993-12-23
+3040668	Bony de Garci	Bony de Garci	Bony de Garci,Pic d' Enclar,Pic d’ Enclar,Puig de Ancla,Puig de Anclá	42.51667	1.46667	T	PK	AD		00				0		1840	Europe/Andorra	2011-11-05
+3040669	Camí d’ Enclar	Cami d' Enclar		42.5	1.48333	R	TRL	AD		00				0		1316	Europe/Andorra	1993-12-23
+3040670	Bosc d’ Enclar	Bosc d' Enclar		42.48333	1.48333	V	FRST	AD		00				0		981	Europe/Andorra	1993-12-23
+3040671	Font de l’ Enciam	Font de l' Enciam		42.61667	1.51667	H	SPNG	AD		00				0		1716	Europe/Andorra	1993-12-23
+3040672	Carrerons d’ Encenrera	Carrerons d' Encenrera		42.53333	1.68333	R	TRL	AD		00				0		2322	Europe/Andorra	1993-12-23
+3040673	Encenrera	Encenrera		42.53333	1.68333	L	LCTY	AD		00				0		2322	Europe/Andorra	1993-12-23
+3040674	Clots d’ Encarners	Clots d' Encarners		42.6	1.58333	H	RVN	AD		00				0		2461	Europe/Andorra	1993-12-23
+3040675	Basera d’ Encarners	Basera d' Encarners		42.5	1.45	T	CLF	AD		00				0		1840	Europe/Andorra	1993-12-23
+3040676	Basera d’ Encarners	Basera d' Encarners		42.46667	1.55	T	CLF	AD		00				0		2341	Europe/Andorra	1993-12-23
+3040677	Solà d’ Encampadana	Sola d' Encampadana		42.55	1.61667	T	SLP	AD		00				0		2206	Europe/Andorra	1993-12-23
+3040678	Pic d’ Encampadana	Pic d' Encampadana	Pic d' Encampadana,Pic d’ Encampadana,Tossa d' Encampdana,Tossa d’ Encampdana,Tossal d' Encampdana,Tossal d’ Encampdana	42.5552	1.63153	T	PK	AD		00				0		2364	Europe/Andorra	2011-11-05
+3040679	Obaga d’ Encampadana	Obaga d' Encampadana		42.55	1.61667	T	SLP	AD		00				0		2206	Europe/Andorra	1993-12-23
+3040680	Font d’ Encampadana	Font d' Encampadana		42.55	1.61667	H	SPNG	AD		00				0		2206	Europe/Andorra	1993-12-23
+3040681	Clot d’ Encampadana	Clot d' Encampadana		42.55	1.61667	H	RVN	AD		00				0		2206	Europe/Andorra	1993-12-23
+3040682	Encampadana	Encampadana		42.56667	1.61667	A	ADMD	AD		00				0		1920	Europe/Andorra	1993-12-23
+3040683	Serra d’ Encamp	Serra d' Encamp		42.53333	1.55	T	RDGE	AD		00				0		1344	Europe/Andorra	1993-12-23
+3040684	Parròquia d'Encamp	Parroquia d'Encamp	Encamp,Parroquia d'Encamp,Parròquia d'Encamp	42.53333	1.63333	A	ADM1	AD		03				13685		2360	Europe/Andorra	2008-03-17
+3040685	Estany d’ Encamp	Estany d' Encamp		42.5	1.65	H	LK	AD		00				0		2542	Europe/Andorra	1993-12-23
+3040686	Encamp	Encamp	Ehnkam,Encamp,en kan pu,enkanpu jiao qu,Энкам,エンカンプ教区,æ©åŽæ™®	42.53451	1.5767	P	PPLA	AD		03				11223		1309	Europe/Andorra	2011-11-05
+3040687	Borda d’ En Cadena	Borda d' En Cadena		42.53333	1.56667	S	HUT	AD		00				0		1418	Europe/Andorra	1993-12-23
+3040688	Pleta d’ Emportona	Pleta d' Emportona		42.53333	1.65	L	GRAZ	AD		00				0		2508	Europe/Andorra	1993-12-23
+3040689	Emportona	Emportona		42.53333	1.65	A	ADMD	AD		00				0		2508	Europe/Andorra	1993-12-23
+3040690	Riu de l’ Empallador	Riu de l' Empallador		42.53333	1.7	H	STM	AD		00				0		2357	Europe/Andorra	1993-12-23
+3040691	Canal de l’ Embut	Canal de l' Embut		42.58333	1.48333	H	RVN	AD		00				0		1809	Europe/Andorra	1993-12-23
+3040692	Clots d’ Embolcar	Clots d' Embolcar		42.61667	1.61667	T	CRQS	AD		00				0		2352	Europe/Andorra	1993-12-23
+3040693	Basers d’ Embolcar	Basers d' Embolcar		42.61667	1.61667	T	CLF	AD		00				0		2352	Europe/Andorra	1993-12-23
+3040694	El Vilar	El Vilar	El Vilar	42.57226	1.60781	P	PPL	AD		02				0		1655	Europe/Andorra	2011-11-05
+3040695	El Vedat	El Vedat		42.46667	1.48333	A	ADMD	AD		00				0		1134	Europe/Andorra	1993-12-23
+3040696	El Turer	El Turer		42.56667	1.53333	T	SPUR	AD		00				0		1669	Europe/Andorra	1993-12-23
+3040697	El Trillar	El Trillar		42.46667	1.5	L	LCTY	AD		00				0		1383	Europe/Andorra	1993-12-23
+3040698	El Tremat	El Tremat		42.53348	1.58056	P	PPL	AD		03				0		1309	Europe/Andorra	2011-04-19
+3040699	El Torrentill	El Torrentill		42.45	1.48333	H	STM	AD		00				0		1111	Europe/Andorra	1993-12-23
+3040700	El Tarter	El Tarter		42.58026	1.64902	P	PPL	AD		02				0		1737	Europe/Andorra	2007-04-16
+3040701	El Tamany	El Tamany		42.63333	1.51667	T	SLP	AD		00				0		1894	Europe/Andorra	1993-12-23
+3040702	Els Tarters	Els Tarters		42.56667	1.68333	L	LCTY	AD		00				0		2340	Europe/Andorra	1993-12-23
+3040703	Els Tarterals	Els Tarterals		42.48333	1.51667	L	LCTY	AD		00				0		2061	Europe/Andorra	1993-12-23
+3040704	Els Rebolians	Els Rebolians		42.53333	1.51667	L	LCTY	AD		00				0		1361	Europe/Andorra	1993-12-23
+3040705	Els Quatre Rocs	Els Quatre Rocs		42.46667	1.53333	T	RKS	AD		00				0		2332	Europe/Andorra	1993-12-23
+3040706	Els Pujols	Els Pujols		42.48333	1.48333	L	LCTY	AD		00				0		981	Europe/Andorra	1993-12-23
+3040707	Els Puiols	Els Puiols		42.56667	1.63333	L	LCTY	AD		00				0		2016	Europe/Andorra	1993-12-23
+3040708	Els Pletius	Els Pletius		42.61667	1.68333	L	LCTY	AD		00				0		2406	Europe/Andorra	1993-12-23
+3040709	Els Plans	Els Plans		42.58142	1.63273	P	PPL	AD		02				0		1722	Europe/Andorra	2011-04-19
+3040710	Els Plans	Els Plans		42.45084	1.50641	L	LCTY	AD		00				0		1394	Europe/Andorra	2011-04-19
+3040711	Els Plans	Els Plans		42.45	1.5	S	FRM	AD		00				0		1614	Europe/Andorra	1993-12-23
+3040712	Els Plans	Els Plans		42.53333	1.51667	A	ADMD	AD		00				0		1361	Europe/Andorra	1993-12-23
+3040713	Els Pessons	Els Pessons		42.51667	1.66667	A	ADMD	AD		00				0		2410	Europe/Andorra	1993-12-23
+3040714	Els Pallers	Els Pallers		42.56667	1.75	L	LCTY	AD		00				0		1923	Europe/Andorra	1993-12-23
+3040715	Els Pallerils	Els Pallerils		42.58333	1.53333	L	LCTY	AD		00				0		1924	Europe/Andorra	1993-12-23
+3040716	Els Padals	Els Padals		42.58333	1.66667	L	LCTY	AD		00				0		2159	Europe/Andorra	1993-12-23
+3040717	Els Orris	Els Orris		42.55	1.46667	L	LCTY	AD		00				0		1585	Europe/Andorra	1993-12-23
+3040718	Els Oriosos	Els Oriosos		42.53333	1.53333	L	LCTY	AD		00				0		1521	Europe/Andorra	1993-12-23
+3040719	El Solà	El Sola		42.55	1.53333	L	LCTY	AD		00				0		1593	Europe/Andorra	1993-12-23
+3040720	Els Obacs	Els Obacs		42.6	1.5	T	SLP	AD		00				0		1923	Europe/Andorra	1993-12-23
+3040721	Els Obacs	Els Obacs		42.55	1.48333	L	LCTY	AD		00				0		1548	Europe/Andorra	1993-12-23
+3040722	Els Maians	Els Maians		42.55	1.61667	L	LCTY	AD		00				0		2206	Europe/Andorra	1993-12-23
+3040723	Els Llacs	Els Llacs		42.53333	1.41667	T	UPLD	AD		00				0		1948	Europe/Andorra	1993-12-23
+3040724	Els Indrets	Els Indrets		42.48333	1.45	L	LCTY	AD		00				0		1195	Europe/Andorra	1993-12-23
+3040725	Els Hortells	Els Hortells		42.45	1.5	L	LCTY	AD		00				0		1614	Europe/Andorra	1993-12-23
+3040726	Els Graus	Els Graus		42.56667	1.73333	L	LCTY	AD		00				0		2096	Europe/Andorra	1993-12-23
+3040727	Els Graus	Els Graus		42.48333	1.56667	A	ADMD	AD		00				0		2231	Europe/Andorra	1993-12-23
+3040728	Els Fontanals	Els Fontanals		42.56667	1.68333	L	LCTY	AD		00				0		2340	Europe/Andorra	1993-12-23
+3040729	Els Feners	Els Feners		42.58333	1.66667	T	SLP	AD		00				0		2159	Europe/Andorra	1993-12-23
+3040730	Els Feners	Els Feners		42.48333	1.48333	L	LCTY	AD		00				0		981	Europe/Andorra	1993-12-23
+3040731	Els Fenerols	Els Fenerols		42.53333	1.56667	L	LCTY	AD		00				0		1418	Europe/Andorra	1993-12-23
+3040732	Els Fenerols	Els Fenerols		42.53333	1.5	L	LCTY	AD		00				0		1357	Europe/Andorra	1993-12-23
+3040733	Els Fenerals	Els Fenerals		42.5	1.46667	A	ADMD	AD		00				0		1678	Europe/Andorra	1993-12-23
+3040734	Els Estanys	Els Estanys		42.48333	1.63333	A	ADMD	AD		00				0		2296	Europe/Andorra	1993-12-23
+3040735	Els Estanyons	Els Estanyons		42.46667	1.61667	L	LCTY	AD		00				0		2448	Europe/Andorra	1993-12-23
+3040736	Els Espiolets	Els Espiolets		42.56667	1.66667	L	LCTY	AD		00				0		1938	Europe/Andorra	1993-12-23
+3040737	El Serrat	El Serrat	Lo Serrat	42.6183	1.53912	P	PPL	AD	AD	05				0		1704	Europe/Andorra	2007-04-16
+3040738	El Seig	El Seig		42.53333	1.58333	A	ADMD	AD		00				0		1571	Europe/Andorra	1993-12-23
+3040739	Els Cuiners	Els Cuiners		42.63333	1.55	L	CLG	AD		00				0		2053	Europe/Andorra	1993-12-23
+3040740	Els Cortals	Els Cortals		42.53333	1.61667	A	ADMD	AD		00				0		2237	Europe/Andorra	1993-12-23
+3040741	Els Corralets	Els Corralets		42.56667	1.55	L	LCTY	AD		00				0		1996	Europe/Andorra	1993-12-23
+3040742	Els Colls	Els Colls		42.55	1.51667	L	LCTY	AD		00				0		1397	Europe/Andorra	1993-12-23
+3040743	Els Collets	Els Collets		42.53333	1.51667	L	LCTY	AD		00				0		1361	Europe/Andorra	1993-12-23
+3040744	Els Collells	Els Collells		42.56667	1.48333	T	PK	AD		00				0		1508	Europe/Andorra	1993-12-23
+3040745	Els Colells	Els Colells		42.6	1.7	L	LCTY	AD		00				0		2354	Europe/Andorra	1993-12-23
+3040746	Els Colells	Els Colells		42.51667	1.7	A	ADMD	AD		00				0		2435	Europe/Andorra	1993-12-23
+3040747	Els Clots	Els Clots		42.56667	1.6	T	SLP	AD		00				0		1655	Europe/Andorra	1993-12-23
+3040748	Els Clots	Els Clots		42.55	1.43333	L	LCTY	AD		00				0		1949	Europe/Andorra	1993-12-23
+3040749	Els Caubets	Els Caubets		42.55	1.48333	T	VAL	AD		00				0		1548	Europe/Andorra	1993-12-23
+3040750	Els Carabedius	Els Carabedius		42.46667	1.45	L	LCTY	AD		00				0		1562	Europe/Andorra	1993-12-23
+3040751	Els Canalons	Els Canalons		42.48333	1.48333	H	RVN	AD		00				0		981	Europe/Andorra	1993-12-23
+3040752	Els Botaders	Els Botaders		42.48333	1.56667	L	LCTY	AD		00				0		2231	Europe/Andorra	1993-12-23
+3040753	Els Bedres	Els Bedres		42.55	1.48333	L	LCTY	AD		00				0		1548	Europe/Andorra	1993-12-23
+3040754	Els Beçolans	Els Becolans		42.63333	1.55	L	LCTY	AD		00				0		2053	Europe/Andorra	1993-12-23
+3040755	Els Bassots	Els Bassots		42.55	1.65	H	LKS	AD		00				0		2432	Europe/Andorra	1993-12-23
+3040756	Els Aubells	Els Aubells		42.56667	1.53333	L	LCTY	AD		00				0		1669	Europe/Andorra	1993-12-23
+3040757	Els Astrells	Els Astrells		42.5	1.56667	L	LCTY	AD		00				0		1776	Europe/Andorra	1993-12-23
+3040758	Els Assaladors	Els Assaladors		42.55	1.66667	L	LCTY	AD		00				0		2224	Europe/Andorra	1993-12-23
+3040759	Els Aspres	Els Aspres		42.56667	1.45	T	RKS	AD		00				0		2137	Europe/Andorra	1993-12-23
+3040760	Els Aspedius	Els Aspedius		42.48333	1.53333	L	LCTY	AD		00				0		2255	Europe/Andorra	1993-12-23
+3040761	El Saquet	El Saquet		42.6	1.53333	A	ADMD	AD		00				0		1695	Europe/Andorra	1993-12-23
+3040762	Els Amorriadors	Els Amorriadors		42.51667	1.6	L	LCTY	AD		00				0		2085	Europe/Andorra	1993-12-23
+3040763	Els Alabars	Els Alabars		42.5	1.48333	L	LCTY	AD		00				0		1316	Europe/Andorra	1993-12-23
+3040764	El Riguer	El Riguer		42.48333	1.55	A	ADMD	AD		00				0		2233	Europe/Andorra	1993-12-23
+3040765	El Remugar	El Remugar		42.56667	1.53333	L	LCTY	AD		00				0		1669	Europe/Andorra	1993-12-23
+3040766	El Ramer	El Ramer		42.56667	1.48333	L	LCTY	AD		00				0		1508	Europe/Andorra	1993-12-23
+3040767	El Pui	El Pui		42.54731	1.51439	P	PPL	AD		04				0		1257	Europe/Andorra	2011-04-19
+3040768	El Pouader	El Pouader	El Ponader,El Pouader	42.53333	1.6	T	RK	AD	AD	00				0		1888	Europe/Andorra	2011-11-05
+3040769	El Pletiu	El Pletiu		42.5	1.6	L	GRAZ	AD		00				0		2416	Europe/Andorra	1993-12-23
+3040770	El Planellet	El Planellet		42.61667	1.53333	L	LCTY	AD		00				0		1609	Europe/Andorra	1993-12-23
+3040771	El Pla	El Pla		42.53333	1.58333	L	LCTY	AD		00				0		1571	Europe/Andorra	1993-12-23
+3040772	El Pas Mal	El Pas Mal		42.53333	1.65	T	PASS	AD		00				0		2508	Europe/Andorra	1993-12-23
+3040773	El Pardal	El Pardal		42.55	1.5	A	ADMD	AD		00				0		1292	Europe/Andorra	1993-12-23
+3040774	El Palinqueró	El Palinquero		42.58333	1.66667	L	LCTY	AD		00				0		2159	Europe/Andorra	1993-12-23
+3040775	El Noguer	El Noguer		42.51667	1.55	A	ADMD	AD		00				0		1322	Europe/Andorra	1993-12-23
+3040776	El Mollar	El Mollar		42.53333	1.6	L	LCTY	AD		00				0		1888	Europe/Andorra	1993-12-23
+3040777	El Moixeret	El Moixeret		42.58333	1.51667	L	LCTY	AD		00				0		1722	Europe/Andorra	1993-12-23
+3040778	El Meligar	El Meligar		42.5	1.61667	T	RDGE	AD		00				0		2560	Europe/Andorra	1993-12-23
+3040779	El Mas	El Mas		42.56667	1.5	A	ADMD	AD		00				0		1636	Europe/Andorra	1993-12-23
+3040780	El Maià	El Maia		42.56667	1.73333	A	ADMD	AD		00				0		2096	Europe/Andorra	1993-12-23
+3040781	El Madriu	El Madriu		42.48333	1.58333	A	ADMD	AD		00				0		2349	Europe/Andorra	1993-12-23
+3040782	El Llempo	El Llempo		42.58333	1.6	L	LCTY	AD		00				0		1828	Europe/Andorra	1993-12-23
+3040783	El Jou	El Jou		42.56667	1.5	A	ADMD	AD		00				0		1636	Europe/Andorra	1993-12-23
+3040784	El Griu	El Griu		42.53333	1.63333	A	ADMD	AD		00				0		2360	Europe/Andorra	1993-12-23
+3040785	El Fornet	El Fornet		42.55	1.6	L	LCTY	AD		00				0		2210	Europe/Andorra	1993-12-23
+3040786	El Fornell	El Fornell		42.51667	1.51667	L	LCTY	AD		00				0		1265	Europe/Andorra	1993-12-23
+3040787	El Fornell	El Fornell		42.45	1.5	L	LCTY	AD		00				0		1614	Europe/Andorra	1993-12-23
+3040788	El Forn	El Forn		42.55	1.6	A	ADMD	AD		00				0		2210	Europe/Andorra	1993-12-23
+3040789	El Fontanal	El Fontanal		42.46667	1.5	L	LCTY	AD		00				0		1383	Europe/Andorra	1993-12-23
+3040790	El Cubil	El Cubil		42.43333	1.55	L	LCTY	AD		00				0		2178	Europe/Andorra	1993-12-23
+3040791	El Cubil	El Cubil		42.53333	1.68333	A	ADMD	AD		00				0		2322	Europe/Andorra	1993-12-23
+3040792	El Cresper	El Cresper		42.51667	1.56667	A	ADMD	AD		00				0		1759	Europe/Andorra	1993-12-23
+3040793	El Cortalet	El Cortalet		42.55	1.51667	L	LCTY	AD		00				0		1397	Europe/Andorra	1993-12-23
+3040794	El Cortalet	El Cortalet		42.51667	1.56667	L	LCTY	AD		00				0		1759	Europe/Andorra	1993-12-23
+3040795	El Corbater	El Corbater		42.55	1.71667	L	LCTY	AD		00				0		2192	Europe/Andorra	1993-12-23
+3040796	El Confòs	El Confos		42.51667	1.58333	A	ADMD	AD		00				0		1994	Europe/Andorra	1993-12-23
+3040797	El Collell	El Collell		42.45	1.5	T	PASS	AD		00				0		1614	Europe/Andorra	1993-12-23
+3040798	El Colitx	El Colitx		42.58333	1.51667	L	LCTY	AD		00				0		1722	Europe/Andorra	1993-12-23
+3040799	El Clos	El Clos		42.53333	1.6	L	LCTY	AD		00				0		1888	Europe/Andorra	1993-12-23
+3040800	El Castellar	El Castellar		42.63333	1.51667	A	ADMD	AD		00				0		1894	Europe/Andorra	1993-12-23
+3040801	El Carregador	El Carregador		42.56667	1.53333	L	LCTY	AD		00				0		1669	Europe/Andorra	1993-12-23
+3040802	El Cardemeller	El Cardemeller		42.55	1.46667	L	LCTY	AD		00				0		1585	Europe/Andorra	1993-12-23
+3040803	El Campús	El Campus		42.43333	1.48333	T	UPLD	AD		00				0		1228	Europe/Andorra	1993-12-23
+3040804	El Bullidor	El Bullidor		42.55	1.71667	L	LCTY	AD		00				0		2192	Europe/Andorra	1993-12-23
+3040805	El Brossós	El Brossos		42.61667	1.53333	A	ADMD	AD		00				0		1609	Europe/Andorra	1993-12-23
+3040806	El Braibal	El Braibal		42.5	1.58333	L	LCTY	AD		00				0		1888	Europe/Andorra	1993-12-23
+3040807	El Bosquet	El Bosquet		42.56667	1.53333	L	LCTY	AD		00				0		1669	Europe/Andorra	1993-12-23
+3040808	El Boscarró	El Boscarro		42.46667	1.48333	L	LCTY	AD		00				0		1134	Europe/Andorra	1993-12-23
+3040809	El Barrerol	El Barrerol		42.43333	1.45	L	LCTY	AD		00				0		877	Europe/Andorra	1993-12-23
+3040810	Camí d’ Easagents	Cami d' Easagents		42.53333	1.61667	R	TRL	AD		00				0		2237	Europe/Andorra	1993-12-23
+3040811	Pleta de Duedra	Pleta de Duedra		42.63333	1.5	L	GRAZ	AD		00				0		1979	Europe/Andorra	1993-12-23
+3040812	Pleta de Duedra	Pleta de Duedra		42.61667	1.56667	L	GRAZ	AD		00				0		2228	Europe/Andorra	1993-12-23
+3040813	Plana Duedra	Plana Duedra		42.58333	1.51667	T	UPLD	AD		00				0		1722	Europe/Andorra	1993-12-23
+3040814	Planella del Duc	Planella del Duc		42.45	1.5	T	SLP	AD		00				0		1614	Europe/Andorra	1993-12-23
+3040815	Canal del Duc	Canal del Duc		42.58333	1.61667	H	RVN	AD		00				0		1707	Europe/Andorra	1993-12-23
+3040816	Canal Dreta	Canal Dreta		42.55	1.53333	H	STM	AD		00				0		1593	Europe/Andorra	1993-12-23
+3040817	Canal Dreta	Canal Dreta		42.51667	1.48333	H	STM	AD		00				0		1839	Europe/Andorra	1993-12-23
+3040818	Port Dret	Port Dret		42.57454	1.70316	T	PASS	AD		00				0		2375	Europe/Andorra	2011-04-19
+3040819	Mas del Diumenge	Mas del Diumenge		42.51667	1.53333	S	FRM	AD		00				0		1460	Europe/Andorra	1993-12-23
+3040820	Canal del Diumenge	Canal del Diumenge		42.51667	1.53333	H	STM	AD		00				0		1460	Europe/Andorra	1993-12-23
+3040821	Clot del Diable	Clot del Diable		42.56667	1.7	T	CRQ	AD		00				0		2375	Europe/Andorra	1993-12-23
+3040822	Devesassa	Devesassa		42.56667	1.6	L	LCTY	AD		00				0		1655	Europe/Andorra	1993-12-23
+3040823	Costa de la Devesa	Costa de la Devesa		42.55	1.45	T	SLP	AD		00				0		1788	Europe/Andorra	1993-12-23
+3040824	Bosc de la Devesa	Bosc de la Devesa		42.5	1.55	V	FRST	AD		00				0		1566	Europe/Andorra	1993-12-23
+3040825	Bony de les Deu Hores	Bony de les Deu Hores		42.53333	1.65	T	SPUR	AD		00				0		2508	Europe/Andorra	1993-12-23
+3040826	Pleta de Dalt	Pleta de Dalt		42.48333	1.43333	L	GRAZ	AD		00				0		1938	Europe/Andorra	1993-12-23
+3040827	Carrera de Dalt	Carrera de Dalt		42.55	1.61667	R	TRL	AD		00				0		2206	Europe/Andorra	1993-12-23
+3040828	Serra del Cussol	Serra del Cussol		42.45	1.45	T	RDGE	AD		00				0		1482	Europe/Andorra	1993-12-23
+3040829	Bosc del Cussol	Bosc del Cussol		42.45	1.45	V	FRST	AD		00				0		1482	Europe/Andorra	1993-12-23
+3040830	Borda de la Cultiassa	Borda de la Cultiassa		42.53333	1.58333	S	HUT	AD		00				0		1571	Europe/Andorra	1993-12-23
+3040831	Obaga del Cultiar	Obaga del Cultiar		42.55	1.6	T	SLP	AD		00				0		2210	Europe/Andorra	1993-12-23
+3040832	Cultiar	Cultiar		42.55	1.58333	L	LCTY	AD		00				0		1499	Europe/Andorra	1993-12-23
+3040833	Canal del Cul	Canal del Cul		42.48333	1.43333	H	STM	AD		00				0		1938	Europe/Andorra	1993-12-23
+3040834	Serrat dels Cuiners	Serrat dels Cuiners		42.63333	1.55	T	SPUR	AD		00				0		2053	Europe/Andorra	1993-12-23
+3040835	Roc dels Cuiners	Roc dels Cuiners		42.63333	1.55	T	RK	AD		00				0		2053	Europe/Andorra	1993-12-23
+3040836	Canal del Cuinal	Canal del Cuinal		42.45	1.48333	H	STM	AD		00				0		1111	Europe/Andorra	1993-12-23
+3040837	Bosc del Cúbol	Bosc del Cubol		42.6	1.7	V	FRST	AD		00				0		2354	Europe/Andorra	1993-12-23
+3040838	Costa del Cubil d’Erts	Costa del Cubil d'Erts		42.58333	1.48333	T	SLP	AD		00				0		1809	Europe/Andorra	1993-12-23
+3040839	Bony del Cubil d’Erts	Bony del Cubil d'Erts		42.58333	1.48333	T	PK	AD		00				0		1809	Europe/Andorra	1993-12-23
+3040840	Solana del Cubil	Solana del Cubil		42.56667	1.46667	T	SLP	AD		00				0		1673	Europe/Andorra	1993-12-23
+3040841	Serrat del Cubil	Serrat del Cubil		42.55	1.66667	T	RDGE	AD		00				0		2224	Europe/Andorra	1993-12-23
+3040842	Riu del Cubil	Riu del Cubil		42.56667	1.46667	H	STM	AD		00				0		1673	Europe/Andorra	1993-12-23
+3040843	Riu del Cubil	Riu del Cubil		42.55568	1.68579	H	STM	AD		00				0		2083	Europe/Andorra	2011-04-19
+3040844	Pla del Cubil	Pla del Cubil		42.53333	1.66667	T	UPLD	AD		00				0		2489	Europe/Andorra	1993-12-23
+3040845	Pic del Cubil	Pic del Cubil	Pic del Cubil	42.53333	1.45	T	PK	AD		00				0		2130	Europe/Andorra	2011-11-05
+3040846	Pic Baix del Cubil	Pic Baix del Cubil		42.53333	1.68333	T	PK	AD		00				0		2322	Europe/Andorra	1993-12-23
+3040847	Pic Alt del Cubil	Pic Alt del Cubil	Pic Alt del Cubil,Pic de Cuvil,Pic de Suvil	42.52808	1.66868	T	PK	AD		00				0		2489	Europe/Andorra	2011-11-05
+3040848	Obaga del Cubil	Obaga del Cubil		42.56667	1.46667	T	SLP	AD		00				0		1673	Europe/Andorra	1993-12-23
+3040849	Llac del Cubil	Llac del Cubil		42.53647	1.66891	H	LK	AD		00				0		2335	Europe/Andorra	2011-04-19
+3040850	Port de Caraussans	Port de Caraussans	Port de Caraussans,Port de Creussans	42.63333	1.46667	T	PASS	AD		00				0		2324	Europe/Andorra	2011-11-05
+3040851	Estany de Creussans	Estany de Creussans		42.63484	1.47697	H	LK	AD		07				0		2291	Europe/Andorra	2007-03-04
+3040852	Creussans	Creussans		42.63355	1.47785	L	LCTY	AD		07				0		2291	Europe/Andorra	2007-03-04
+3040853	Planell de la Creueta	Planell de la Creueta		42.55	1.55	T	UPLD	AD		00				0		2097	Europe/Andorra	1993-12-23
+3040854	Creu de Noral	Creu de Noral		42.56667	1.55	L	LCTY	AD		00				0		1996	Europe/Andorra	1993-12-23
+3040855	Serra de la Creu	Serra de la Creu		42.48333	1.51667	T	MT	AD		00				0		2061	Europe/Andorra	1993-12-23
+3040856	Roc de la Creu	Roc de la Creu		42.56667	1.48333	T	RK	AD		00				0		1508	Europe/Andorra	1993-12-23
+3040857	Borda del Cresper	Borda del Cresper		42.53333	1.56667	S	HUT	AD		00				0		1418	Europe/Andorra	1993-12-23
+3040858	Rocs del Cresp	Rocs del Cresp		42.58333	1.51667	T	RKS	AD		00				0		1722	Europe/Andorra	1993-12-23
+3040859	Roc del Cresp	Roc del Cresp		42.56667	1.48333	T	SPUR	AD		00				0		1508	Europe/Andorra	1993-12-23
+3040860	Canal del Cresp	Canal del Cresp		42.58333	1.51667	H	STM	AD		00				0		1722	Europe/Andorra	1993-12-23
+3040861	Font del Crau	Font del Crau		42.6	1.51667	H	SPNG	AD		00				0		1445	Europe/Andorra	1993-12-23
+3040862	Pla de la Cot	Pla de la Cot		42.53333	1.46667	T	UPLD	AD		00				0		1846	Europe/Andorra	1993-12-23
+3040863	Canal de les Costes	Canal de les Costes		42.51667	1.53333	H	STM	AD		00				0		1460	Europe/Andorra	1993-12-23
+3040864	Canal de Costa Verda	Canal de Costa Verda		42.5	1.56667	H	STM	AD		00				0		1776	Europe/Andorra	1993-12-23
+3040865	Collet de Costasseda	Collet de Costasseda		42.48333	1.5	T	PASS	AD		00				0		1631	Europe/Andorra	1993-12-23
+3040866	Bosc de la Costassa	Bosc de la Costassa		42.55	1.51667	V	FRST	AD		00				0		1397	Europe/Andorra	1993-12-23
+3040867	Barranc de la Costa Rodona	Barranc de la Costa Rodona		42.56667	1.73333	H	STM	AD		00				0		2096	Europe/Andorra	1993-12-23
+3040868	Font de la Costa Gran	Font de la Costa Gran		42.51667	1.48333	H	SPNG	AD		00				0		1839	Europe/Andorra	1993-12-23
+3040869	Bony de la Costa del Sodorn	Bony de la Costa del Sodorn		42.5	1.45	T	PK	AD		00				0		1840	Europe/Andorra	1993-12-23
+3040870	Canal de la Costa de les Salineres	Canal de la Costa de les Salineres		42.5	1.46667	H	STM	AD		00				0		1678	Europe/Andorra	1993-12-23
+3040871	Costa de les Neres	Costa de les Neres		42.55	1.55	A	ADMD	AD		00				0		2097	Europe/Andorra	1993-12-23
+3040872	Canal de la Costa de les Gerderes	Canal de la Costa de les Gerderes		42.55	1.6	H	RVN	AD		00				0		2210	Europe/Andorra	1993-12-23
+3040873	Collet de la Costa del Bony Roig	Collet de la Costa del Bony Roig		42.6	1.61667	T	PASS	AD		00				0		2271	Europe/Andorra	1993-12-23
+3040874	Ras de la Costa de l’Avier	Ras de la Costa de l'Avier		42.58333	1.5	T	SLP	AD		00				0		1595	Europe/Andorra	1993-12-23
+3040875	Font de la Costa de l’Avier	Font de la Costa de l'Avier		42.56667	1.53333	H	SPNG	AD		00				0		1669	Europe/Andorra	1993-12-23
+3040876	Canal de Costa de l’Avier	Canal de Costa de l'Avier		42.58333	1.48333	H	STM	AD		00				0		1809	Europe/Andorra	1993-12-23
+3040877	Roc de la Costa	Roc de la Costa		42.56667	1.48333	T	RK	AD		00				0		1508	Europe/Andorra	1993-12-23
+3040878	Solana del Cosp	Solana del Cosp		42.56667	1.61667	T	SLP	AD		00				0		1920	Europe/Andorra	1993-12-23
+3040879	Roca Cosconera	Roca Cosconera		42.48333	1.56667	T	RK	AD		00				0		2231	Europe/Andorra	1993-12-23
+3040880	Font de la Coruvilla	Font de la Coruvilla		42.58333	1.46667	H	SPNG	AD		00				0		1643	Europe/Andorra	1993-12-23
+3040881	Canals de la Coruvilla	Canals de la Coruvilla		42.58333	1.46667	H	RVN	AD		00				0		1643	Europe/Andorra	1993-12-23
+3040882	Borda de la Coruvilla	Borda de la Coruvilla		42.58333	1.46667	S	FRM	AD		00				0		1643	Europe/Andorra	1993-12-23
+3040883	Corts d’Ern	Corts d'Ern	Corts d'Aern,Corts d'Ern,Corts d’Aern,Corts d’Ern	42.5	1.48333	L	LCTY	AD		00				0		1316	Europe/Andorra	2011-11-05
+3040884	Bosc de les Corts	Bosc de les Corts		42.56667	1.53333	V	FRST	AD		00				0		1669	Europe/Andorra	1993-12-23
+3040885	Cort d’Esteve	Cort d'Esteve		42.6	1.51667	L	LCTY	AD		00				0		1445	Europe/Andorra	1993-12-23
+3040886	Cort de Rossell	Cort de Rossell		42.46667	1.48333	L	LCTY	AD		00				0		1134	Europe/Andorra	1993-12-23
+3040887	Cort Cremada	Cort Cremada		42.56667	1.53333	L	LCTY	AD		00				0		1669	Europe/Andorra	1993-12-23
+3040888	Bosc de les Cortanbelles	Bosc de les Cortanbelles		42.46667	1.45	V	FRST	AD		00				0		1562	Europe/Andorra	1993-12-23
+3040889	Canal del Cortal Vell	Canal del Cortal Vell		42.58333	1.46667	H	STM	AD		00				0		1643	Europe/Andorra	1993-12-23
+3040890	Cortal Vell	Cortal Vell		42.58333	1.46667	L	LCTY	AD		00				0		1643	Europe/Andorra	1993-12-23
+3040891	Cortals de Sispony	Cortals de Sispony	Corfots de Sispony,Cortals de Sispony	42.53333	1.5	L	LCTY	AD	AD	00				0		1357	Europe/Andorra	2011-11-05
+3040892	Cortals de Fontaneda	Cortals de Fontaneda		42.45	1.46667	L	LCTY	AD		00				0		935	Europe/Andorra	1993-12-23
+3040893	Riu dels Cortals	Riu dels Cortals		42.53333	1.58333	H	STM	AD		00				0		1571	Europe/Andorra	1993-12-23
+3040894	Riu dels Cortals	Riu dels Cortals		42.53333	1.51667	H	STM	AD		00				0		1361	Europe/Andorra	1993-12-23
+3040895	Carretera dels Cortals	Carretera dels Cortals		42.53333	1.58333	R	RD	AD		00				0		1571	Europe/Andorra	1993-12-23
+3040896	Camí dels Cortals	Cami dels Cortals		42.53333	1.53333	R	TRL	AD		00				0		1521	Europe/Andorra	1993-12-23
+3040897	Canal del Cortalet	Canal del Cortalet		42.48333	1.48333	H	STM	AD		00				0		981	Europe/Andorra	1993-12-23
+3040898	Camí del Cortal de la Serra	Cami del Cortal de la Serra		42.53333	1.5	R	TRL	AD		00				0		1357	Europe/Andorra	1993-12-23
+3040899	Mas del Cortal	Mas del Cortal		42.56667	1.6	S	FRM	AD		00				0		1655	Europe/Andorra	1993-12-23
+3040900	Canal del Cortà	Canal del Corta		42.5	1.48333	H	STM	AD		00				0		1316	Europe/Andorra	1993-12-23
+3040901	Canal de la Corruga	Canal de la Corruga		42.58333	1.63333	H	RVN	AD		00				0		1722	Europe/Andorra	1993-12-23
+3040902	Bosc de la Corruga	Bosc de la Corruga		42.56667	1.65	V	FRST	AD		00				0		1988	Europe/Andorra	1993-12-23
+3040903	Font del Correus	Font del Correus		42.56667	1.71667	H	SPNG	AD		00				0		2219	Europe/Andorra	1993-12-23
+3040904	Corrals de la Mentirosa	Corrals de la Mentirosa		42.43333	1.51667	S	RUIN	AD		00				0		2031	Europe/Andorra	1993-12-23
+3040905	Serra dels Corrals	Serra dels Corrals		42.55	1.45	T	MT	AD		00				0		1788	Europe/Andorra	1993-12-23
+3040906	Serrat de Corpalanca	Serrat de Corpalanca		42.53333	1.46667	T	RDGE	AD		00				0		1846	Europe/Andorra	1993-12-23
+3040907	Canal de Cordabalba	Canal de Cordabalba		42.48333	1.55	H	STM	AD		00				0		2233	Europe/Andorra	1993-12-23
+3040908	Roc dels Corbs	Roc dels Corbs		42.5	1.51667	T	RK	AD		00				0		1410	Europe/Andorra	1993-12-23
+3040909	Torrent de les Corbelles	Torrent de les Corbelles		42.55	1.6	H	STM	AD		00				0		2210	Europe/Andorra	1993-12-23
+3040910	Roca Corba	Roca Corba		42.51667	1.53333	T	RK	AD		00				0		1460	Europe/Andorra	1993-12-23
+3040911	Font del Corb	Font del Corb		42.55	1.46667	H	SPNG	AD		00				0		1585	Europe/Andorra	1993-12-23
+3040912	Canal del Corb	Canal del Corb		42.55	1.5	H	STM	AD		00				0		1292	Europe/Andorra	1993-12-23
+3040913	Canal del Corb	Canal del Corb		42.53333	1.56667	H	STM	AD		00				0		1418	Europe/Andorra	1993-12-23
+3040914	Camí del Corb	Cami del Corb		42.63333	1.51667	R	TRL	AD		00				0		1894	Europe/Andorra	1993-12-23
+3040915	Basers del Corb	Basers del Corb		42.63333	1.51667	T	CLF	AD		00				0		1894	Europe/Andorra	1993-12-23
+3040916	Serrat del Corantell	Serrat del Corantell		42.53333	1.5	T	RDGE	AD		00				0		1357	Europe/Andorra	1993-12-23
+3040917	Roc de la Copa	Roc de la Copa		42.5	1.46667	T	RK	AD		00				0		1678	Europe/Andorra	1993-12-23
+3040918	Font de Conxa	Font de Conxa		42.6	1.65	H	SPNG	AD		00				0		2131	Europe/Andorra	1993-12-23
+3040919	Bosc de Conxa	Bosc de Conxa		42.6	1.65	V	FRST	AD		00				0		2131	Europe/Andorra	1993-12-23
+3040920	Solana del Contador	Solana del Contador		42.48333	1.43333	T	SLP	AD		00				0		1938	Europe/Andorra	1993-12-23
+3040921	Font del Coniol	Font del Coniol		42.5	1.58333	H	SPNG	AD		00				0		1888	Europe/Andorra	1993-12-23
+3040922	Costa del Congost	Costa del Congost		42.6	1.46667	T	SLP	AD		00				0		2421	Europe/Andorra	1993-12-23
+3040923	Conangle	Conangle		42.43333	1.51667	L	LCTY	AD		00				0		2031	Europe/Andorra	1993-12-23
+3040924	Cóms de Jan	Coms de Jan		42.63333	1.61667	L	LCTY	AD		00				0		2541	Europe/Andorra	1993-12-23
+3040925	Roc dels Cóms	Roc dels Coms		42.63333	1.63333	T	CLF	AD		00				0		2603	Europe/Andorra	1993-12-23
+3040926	Planells dels Cóms	Planells dels Coms		42.55	1.6	T	UPLD	AD		00				0		2210	Europe/Andorra	1993-12-23
+3040927	Obaga dels Cóms	Obaga dels Coms		42.48333	1.41667	T	SLP	AD		00				0		1920	Europe/Andorra	1993-12-23
+3040928	Font dels Cóms	Font dels Coms		42.45	1.45	H	SPNG	AD		00				0		1482	Europe/Andorra	1993-12-23
+3040929	Canal dels Cóms	Canal dels Coms		42.48333	1.41667	H	STM	AD		00				0		1920	Europe/Andorra	1993-12-23
+3040930	Bosc dels Cóms	Bosc dels Coms		42.53333	1.46667	V	FRST	AD		00				0		1846	Europe/Andorra	1993-12-23
+3040931	Riu del Comís Vell	Riu del Comis Vell		42.63667	1.52189	H	STM	AD		07				0		2334	Europe/Andorra	2007-03-04
+3040932	Comís Vell	Comis Vell		42.63748	1.52098	L	LCTY	AD		07				0		2334	Europe/Andorra	2007-03-04
+3040933	Borda del Comet	Borda del Comet		42.56667	1.58333	S	HUT	AD		00				0		1919	Europe/Andorra	1993-12-23
+3040934	Comes de Banyàs	Comes de Banyas		42.55	1.51667	L	LCTY	AD		00				0		1397	Europe/Andorra	1993-12-23
+3040935	Bosc de Comes Beçoses	Bosc de Comes Becoses		42.51667	1.58333	V	FRST	AD		00				0		1994	Europe/Andorra	1993-12-23
+3040936	Solà de les Comes	Sola de les Comes		42.58333	1.5	T	SLP	AD		00				0		1595	Europe/Andorra	1993-12-23
+3040937	Portell de les Comes	Portell de les Comes		42.5	1.46667	T	PASS	AD		00				0		1678	Europe/Andorra	1993-12-23
+3040938	Canals de les Comes	Canals de les Comes		42.56667	1.51667	H	RVN	AD		00				0		1500	Europe/Andorra	1993-12-23
+3040939	Borda de les Comes	Borda de les Comes		42.53333	1.58333	S	FRM	AD		00				0		1571	Europe/Andorra	1993-12-23
+3040940	Bosc dels Comellassos	Bosc dels Comellassos		42.6	1.66667	V	FRST	AD		00				0		1858	Europe/Andorra	1993-12-23
+3040941	Costa del Comellar Llarg	Costa del Comellar Llarg		42.56667	1.61667	T	SLP	AD		00				0		1920	Europe/Andorra	1993-12-23
+3040942	Camí del Comellar Llarg	Cami del Comellar Llarg		42.56667	1.61667	R	TRL	AD		00				0		1920	Europe/Andorra	1993-12-23
+3040943	Clot de la Comellada	Clot de la Comellada		42.53333	1.45	H	RVN	AD		00				0		2130	Europe/Andorra	1993-12-23
+3040944	Riu de la Comella	Riu de la Comella		42.5	1.53333	H	STM	AD		00				0		1574	Europe/Andorra	1993-12-23
+3040945	Carretera de la Comella	Carretera de la Comella		42.51667	1.55	R	RD	AD		00				0		1322	Europe/Andorra	1993-12-23
+3040946	Bony de Comascura	Bony de Comascura		42.5	1.55	T	SPUR	AD		00				0		1566	Europe/Andorra	1993-12-23
+3040947	Canal de Coma Sansa	Canal de Coma Sansa		42.48333	1.46667	H	STM	AD		00				0		1148	Europe/Andorra	1993-12-23
+3040948	Riu de la Comarqueta d’Incles	Riu de la Comarqueta d'Incles		42.6	1.61667	H	STM	AD		00				0		2271	Europe/Andorra	1993-12-23
+3040949	Collet de la Comarqueta d’Incles	Collet de la Comarqueta d'Incles		42.6	1.61667	T	PASS	AD		00				0		2271	Europe/Andorra	1993-12-23
+3040950	Comarqueta d’Incles	Comarqueta d'Incles		42.6	1.61667	L	LCTY	AD		00				0		2271	Europe/Andorra	1993-12-23
+3040951	Tosa de la Comarqueta	Tosa de la Comarqueta		42.56667	1.73333	T	UPLD	AD		00				0		2096	Europe/Andorra	1993-12-23
+3040952	Font de la Comarqueta	Font de la Comarqueta		42.56667	1.71667	H	SPNG	AD		00				0		2219	Europe/Andorra	1993-12-23
+3040953	Basers de la Comarqueta	Basers de la Comarqueta		42.58333	1.71667	T	CLF	AD		00				0		2553	Europe/Andorra	1993-12-23
+3040954	Riu de la Comarca de les Fonts	Riu de la Comarca de les Fonts		42.6	1.61667	H	STM	AD		00				0		2271	Europe/Andorra	1993-12-23
+3040955	Obaga de la Comarca	Obaga de la Comarca		42.56667	1.46667	T	SLP	AD		00				0		1673	Europe/Andorra	1993-12-23
+3040956	Font de la Comarca	Font de la Comarca		42.56667	1.45	H	SPNG	AD		00				0		2137	Europe/Andorra	1993-12-23
+3040957	Riu de Coma Pedrosa	Riu de Coma Pedrosa		42.58333	1.46667	H	STM	AD		00				0		1643	Europe/Andorra	1993-12-23
+3040958	Pleta de Coma Pedrosa	Pleta de Coma Pedrosa		42.58333	1.45	L	GRAZ	AD		00				0		2156	Europe/Andorra	1993-12-23
+3040959	Pic de Coma Pedrosa	Pic de Coma Pedrosa	Pic Alt de la Coma Pedrosa,Pic Alt de la Pedrosa,Pic de Coma Pedrosa	42.5917	1.44428	T	PK	AD		00				0		2406	Europe/Andorra	2011-11-05
+3040960	Obaga de Coma Pedrosa	Obaga de Coma Pedrosa		42.58387	1.44182	T	SLP	AD		00				0		2350	Europe/Andorra	2011-04-19
+3040961	Grau de Coma Pedrosa	Grau de Coma Pedrosa		42.58333	1.46667	T	SLP	AD		00				0		1643	Europe/Andorra	1993-12-23
+3040962	Collet de Coma Pedrosa	Collet de Coma Pedrosa		42.58333	1.45	T	PK	AD		00				0		2156	Europe/Andorra	1993-12-23
+3040963	Camí de Coma Pedrosa	Cami de Coma Pedrosa		42.58333	1.48333	R	TRL	AD		00				0		1809	Europe/Andorra	1993-12-23
+3040964	Coma Pedrosa	Coma Pedrosa	Coma Pedrosa	42.58333	1.43333	A	ADMD	AD		00				0		2412	Europe/Andorra	2011-11-05
+3040965	Serra de Coma Obaga i Ferreroles	Serra de Coma Obaga i Ferreroles		42.61667	1.56667	T	RDGE	AD		00				0		2228	Europe/Andorra	1993-12-23
+3040966	Solana de Coma Obaga	Solana de Coma Obaga		42.61667	1.55	T	SLP	AD		00				0		2007	Europe/Andorra	1993-12-23
+3040967	Serra de Coma Obaga	Serra de Coma Obaga		42.61667	1.56667	T	RDGE	AD		00				0		2228	Europe/Andorra	1993-12-23
+3040968	Pala de Coma Obaga	Pala de Coma Obaga		42.61667	1.56667	T	SLP	AD		00				0		2228	Europe/Andorra	1993-12-23
+3040969	Coma Obaga	Coma Obaga		42.6	1.55	A	ADMD	AD		00				0		2298	Europe/Andorra	1993-12-23
+3040970	Comangerra	Comangerra		42.56667	1.5	T	SPUR	AD		00				0		1636	Europe/Andorra	1993-12-23
+3040971	Canal de Coma Llonga	Canal de Coma Llonga		42.56667	1.6	H	STM	AD		00				0		1655	Europe/Andorra	1993-12-23
+3040972	Riu de Comallempla	Riu de Comallempla		42.56667	1.48333	H	STM	AD		00				0		1508	Europe/Andorra	1993-12-23
+3040973	Portella de Comallempla	Portella de Comallempla		42.56667	1.45	T	PASS	AD		00				0		2137	Europe/Andorra	1993-12-23
+3040974	Camí de Comallempla	Cami de Comallempla		42.56667	1.48333	R	TRL	AD		00				0		1508	Europe/Andorra	1993-12-23
+3040975	Bordes de Comallempla	Bordes de Comallempla		42.56667	1.46667	S	HUTS	AD		00				0		1673	Europe/Andorra	1993-12-23
+3040976	Comallempla	Comallempla		42.56667	1.46667	A	ADMD	AD		00				0		1673	Europe/Andorra	1993-12-23
+3040977	Canal de Coma Fregona	Canal de Coma Fregona		42.58333	1.51667	H	STM	AD		00				0		1722	Europe/Andorra	1993-12-23
+3040978	Canal de Coma Fregona	Canal de Coma Fregona		42.56667	1.51667	H	STM	AD		00				0		1500	Europe/Andorra	1993-12-23
+3040979	Coma Estreta	Coma Estreta		42.58333	1.55	L	LCTY	AD		00				0		2357	Europe/Andorra	1993-12-23
+3040980	Coma Estremera	Coma Estremera		42.51667	1.68333	A	ADMD	AD		00				0		2352	Europe/Andorra	1993-12-23
+3040981	Col de la Portaneille	Col de la Portaneille	Col de la Portaneille,Portella de la Coma de Varilles	42.61667	1.65	T	PASS	AD		00				0		2567	Europe/Andorra	2011-11-05
+3040982	Pics de la Portaneille	Pics de la Portaneille	Passada,Pic de la Coma de Varilles,Pic de la Passada,Picos de la Passade,Pics de la Passade,Pics de la Portaneille	42.61667	1.66667	T	PKS	AD		00				0		2536	Europe/Andorra	2011-11-05
+3040983	Rocs de Coma de Teix	Rocs de Coma de Teix		42.46667	1.46667	T	RKS	AD		00				0		1340	Europe/Andorra	1993-12-23
+3040984	Coma de Ransol	Coma de Ransol		42.6	1.63333	A	ADMD	AD		00				0		1893	Europe/Andorra	1993-12-23
+3040985	Solana de la Coma dels Llops	Solana de la Coma dels Llops		42.51667	1.63333	T	SLP	AD		00				0		2379	Europe/Andorra	1993-12-23
+3040986	Riu de la Coma dels Llops	Riu de la Coma dels Llops		42.52722	1.60965	H	STM	AD		00				0		2101	Europe/Andorra	2011-04-19
+3040987	Pleta de la Coma dels Llops	Pleta de la Coma dels Llops		42.51667	1.61667	L	GRAZ	AD		00				0		2254	Europe/Andorra	1993-12-23
+3040988	Cap de la Coma dels Llops	Cap de la Coma dels Llops		42.50769	1.62525	T	RDGE	AD		00				0		2666	Europe/Andorra	2011-04-19
+3040989	Bosc de la Coma dels Llops	Bosc de la Coma dels Llops		42.51667	1.61667	V	FRST	AD		00				0		2254	Europe/Andorra	1993-12-23
+3040990	Coma dels Llops	Coma dels Llops		42.51667	1.61667	A	ADMD	AD		00				0		2254	Europe/Andorra	1993-12-23
+3040991	Clot de la Coma del Prat	Clot de la Coma del Prat		42.51667	1.46667	H	RVN	AD		00				0		1840	Europe/Andorra	1993-12-23
+3040992	Clot de la Coma del Pou	Clot de la Coma del Pou		42.51667	1.48333	H	RVN	AD		00				0		1839	Europe/Andorra	1993-12-23
+3040993	Riu de la Coma del Mig	Riu de la Coma del Mig		42.63333	1.51667	H	STM	AD		00				0		1894	Europe/Andorra	1993-12-23
+3040994	Riu de la Coma del Forat	Riu de la Coma del Forat		42.63333	1.5	H	STM	AD		00				0		1979	Europe/Andorra	1993-12-23
+3040995	Costa de la Coma del Forat	Costa de la Coma del Forat		42.63333	1.48333	T	SLP	AD		00				0		2283	Europe/Andorra	1993-12-23
+3040996	Coma del Favar	Coma del Favar		42.51667	1.58333	L	LCTY	AD		00				0		1994	Europe/Andorra	1993-12-23
+3040997	Clot de la Coma de la Sella	Clot de la Coma de la Sella		42.51667	1.48333	H	RVN	AD		00				0		1839	Europe/Andorra	1993-12-23
+3040998	Solà de la Coma de Cardes	Sola de la Coma de Cardes		42.58333	1.61667	T	SLP	AD		00				0		1707	Europe/Andorra	1993-12-23
+3040999	Tosa de Coma Bella	Tosa de Coma Bella		42.58333	1.68333	T	UPLD	AD		00				0		2294	Europe/Andorra	1993-12-23
+3041000	Font de Coma Bella	Font de Coma Bella		42.45	1.5	H	SPNG	AD		00				0		1614	Europe/Andorra	1993-12-23
+3041001	Canal de Coma Bella	Canal de Coma Bella		42.45	1.48333	H	STM	AD		00				0		1111	Europe/Andorra	1993-12-23
+3041002	Coma Bella	Coma Bella		42.45	1.5	L	LCTY	AD		00				0		1614	Europe/Andorra	1993-12-23
+3041003	Planell de Coma Aubosa	Planell de Coma Aubosa		42.58333	1.5	T	UPLD	AD		00				0		1595	Europe/Andorra	1993-12-23
+3041004	Clot de Coma Aubosa	Clot de Coma Aubosa		42.58333	1.48333	H	RVN	AD		00				0		1809	Europe/Andorra	1993-12-23
+3041005	Roc de la Coma	Roc de la Coma		42.51667	1.55	T	RK	AD		00				0		1322	Europe/Andorra	1993-12-23
+3041006	Riu de la Coma	Riu de la Coma		42.58333	1.63333	H	STM	AD		00				0		1722	Europe/Andorra	1993-12-23
+3041007	Riu de la Coma	Riu de la Coma		42.45	1.46667	H	STM	AD		00				0		935	Europe/Andorra	1993-12-23
+3041008	Prats de Coma	Prats de Coma		42.56667	1.46667	L	GRAZ	AD		00				0		1673	Europe/Andorra	1993-12-23
+3041009	Pont de la Coma	Pont de la Coma		42.55	1.46667	S	BDG	AD		00				0		1585	Europe/Andorra	1993-12-23
+3041010	Collet de la Coma	Collet de la Coma		42.65	1.51667	T	PASS	AD		00				0		2546	Europe/Andorra	1993-12-23
+3041011	Collada de la Coma	Collada de la Coma		42.6	1.61667	T	PASS	AD		00				0		2271	Europe/Andorra	1993-12-23
+3041012	Canal de la Coma	Canal de la Coma		42.61667	1.55	H	STM	AD		00				0		2007	Europe/Andorra	1993-12-23
+3041013	Canal de la Coma	Canal de la Coma		42.55	1.55	H	STM	AD		00				0		2097	Europe/Andorra	1993-12-23
+3041014	Canal de la Coma	Canal de la Coma		42.6	1.51667	H	RVN	AD		00				0		1445	Europe/Andorra	1993-12-23
+3041015	Bosc de Coma	Bosc de Coma		42.53333	1.55	V	FRST	AD		00				0		1344	Europe/Andorra	1993-12-23
+3041016	Bony de la Coma	Bony de la Coma		42.55	1.53333	T	SPUR	AD		00				0		1593	Europe/Andorra	1993-12-23
+3041017	Rocs del Colomer	Rocs del Colomer		42.53333	1.51667	T	SPUR	AD		00				0		1361	Europe/Andorra	1993-12-23
+3041018	Collet dels Colls	Collet dels Colls		42.55	1.51667	T	PASS	AD		00				0		1397	Europe/Andorra	1993-12-23
+3041019	Solana de Coll Pa	Solana de Coll Pa		42.55	1.43333	T	SLP	AD		00				0		1949	Europe/Andorra	1993-12-23
+3041020	Serrat de Coll Pa	Serrat de Coll Pa		42.55	1.43333	T	RDGE	AD		00				0		1949	Europe/Andorra	1993-12-23
+3041021	Planell de Coll Pa	Planell de Coll Pa		42.48333	1.56667	T	UPLD	AD		00				0		2231	Europe/Andorra	1993-12-23
+3041022	Pic de Coll Pa	Pic de Coll Pa		42.51667	1.48333	T	PK	AD		00				0		1839	Europe/Andorra	1993-12-23
+3041023	Bosc de Coll Pa	Bosc de Coll Pa		42.48333	1.55	V	FRST	AD		00				0		2233	Europe/Andorra	1993-12-23
+3041024	Basers de Coll Pa	Basers de Coll Pa		42.48333	1.56667	T	CLF	AD		00				0		2231	Europe/Andorra	1993-12-23
+3041025	Canal de Coll Jovell	Canal de Coll Jovell		42.5	1.56667	H	STM	AD		00				0		1776	Europe/Andorra	1993-12-23
+3041026	Canal de Collet Purgat	Canal de Collet Purgat		42.46667	1.48333	H	STM	AD		00				0		1134	Europe/Andorra	1993-12-23
+3041027	Clot del Collet de Font Podrida	Clot del Collet de Font Podrida		42.58333	1.46667	T	SLP	AD		00				0		1643	Europe/Andorra	1993-12-23
+3041028	Camí dels Collells	Cami dels Collells		42.56667	1.46667	R	TRL	AD		00				0		1673	Europe/Andorra	1993-12-23
+3041029	Carretera del Coll d’Ordino	Carretera del Coll d'Ordino		42.55	1.53333	R	RD	AD		00				0		1593	Europe/Andorra	1993-12-23
+3041030	Camí del Coll d’Ordino	Cami del Coll d'Ordino		42.55	1.56667	R	TRL	AD		00				0		1828	Europe/Andorra	1993-12-23
+3041031	Font del Coll de Vista	Font del Coll de Vista		42.48333	1.45	H	SPNG	AD		00				0		1195	Europe/Andorra	1993-12-23
+3041032	Canal del Coll de Vista	Canal del Coll de Vista		42.48333	1.45	H	STM	AD		00				0		1195	Europe/Andorra	1993-12-23
+3041033	Canal del Coll de Turer	Canal del Coll de Turer		42.56667	1.46667	H	STM	AD		00				0		1673	Europe/Andorra	1993-12-23
+3041034	Camí de Coll de Turer	Cami de Coll de Turer		42.56667	1.46667	R	TRL	AD		00				0		1673	Europe/Andorra	1993-12-23
+3041035	Canal de Coll d’Eres	Canal de Coll d'Eres		42.5	1.51667	H	STM	AD		00				0		1410	Europe/Andorra	1993-12-23
+3041036	Camí del Coll dels Isards	Cami del Coll dels Isards		42.51667	1.73333	R	TRL	AD		00				0		2484	Europe/Andorra	1993-12-23
+3041037	Canal del Coll de l’Obac	Canal del Coll de l'Obac		42.48333	1.48333	H	STM	AD		00				0		981	Europe/Andorra	1993-12-23
+3041038	Canal del Coll de les Cases	Canal del Coll de les Cases		42.56667	1.5	H	STM	AD		00				0		1636	Europe/Andorra	1993-12-23
+3041039	Bony del Coll de l’Era	Bony del Coll de l'Era		42.48333	1.45	T	SPUR	AD		00				0		1195	Europe/Andorra	1993-12-23
+3041040	Riu del Coll de l’Aquell	Riu del Coll de l'Aquell		42.48333	1.43333	H	STM	AD		00				0		1938	Europe/Andorra	1993-12-23
+3041041	Canal del Coll de l’Acaumader	Canal del Coll de l'Acaumader		42.48333	1.46667	H	STM	AD		00				0		1148	Europe/Andorra	1993-12-23
+3041042	Canal del Coll de la Cauba	Canal del Coll de la Cauba		42.58333	1.61667	H	STM	AD		00				0		1707	Europe/Andorra	1993-12-23
+3041043	Canal del Coll de la Basera	Canal del Coll de la Basera		42.58333	1.65	H	RVN	AD		00				0		1767	Europe/Andorra	1993-12-23
+3041044	Camí del Coll d’Arenes	Cami del Coll d'Arenes		42.6	1.58333	R	TRL	AD		00				0		2461	Europe/Andorra	1993-12-23
+3041045	Pala de Coll Carnisser	Pala de Coll Carnisser		42.6	1.46667	T	SLP	AD		00				0		2421	Europe/Andorra	1993-12-23
+3041046	Collada de Coll Carnisser	Collada de Coll Carnisser		42.6	1.48333	T	PASS	AD		00				0		2441	Europe/Andorra	1993-12-23
+3041047	Prats de Collart	Prats de Collart		42.58333	1.65	L	GRAZ	AD		00				0		1767	Europe/Andorra	1993-12-23
+3041048	Canal de Collart	Canal de Collart		42.58333	1.65	H	STM	AD		00				0		1767	Europe/Andorra	1993-12-23
+3041049	Bosc de Collart	Bosc de Collart		42.56667	1.66667	V	FRST	AD		00				0		1938	Europe/Andorra	1993-12-23
+3041050	La Colladeta	La Colladeta		42.55	1.55	T	PASS	AD		00				0		2097	Europe/Andorra	1993-12-23
+3041051	Bony de les Collades	Bony de les Collades		42.55	1.51667	T	MT	AD		00				0		1397	Europe/Andorra	1993-12-23
+3041052	Canal de la Collada Gran	Canal de la Collada Gran		42.5	1.48333	H	STM	AD		00				0		1316	Europe/Andorra	1993-12-23
+3041053	Camí de la Collada de Sanfons	Cami de la Collada de Sanfons		42.58333	1.45	R	TRL	AD		00				0		2156	Europe/Andorra	1993-12-23
+3041054	Camí de la Collada d’Enradort	Cami de la Collada d'Enradort		42.53333	1.61667	R	TRL	AD		00				0		2237	Europe/Andorra	1993-12-23
+3041055	Camí de la Collada de la Maiana	Cami de la Collada de la Maiana		42.48333	1.61667	R	TRL	AD		00				0		2217	Europe/Andorra	1993-12-23
+3041056	Camí de la Collada de Ferreroles	Cami de la Collada de Ferreroles		42.6	1.56667	R	TRL	AD		00				0		2513	Europe/Andorra	1993-12-23
+3041057	Clots de la Collada	Clots de la Collada		42.61667	1.61667	H	RVN	AD		00				0		2352	Europe/Andorra	1993-12-23
+3041058	Bosc de la Collada	Bosc de la Collada		42.51667	1.46667	V	FRST	AD		00				0		1840	Europe/Andorra	1993-12-23
+3041059	Planell del Colitx	Planell del Colitx		42.61667	1.51667	T	UPLD	AD		00				0		1716	Europe/Andorra	1993-12-23
+3041060	Font de la Colilla	Font de la Colilla		42.51667	1.6	H	SPNG	AD		00				0		2085	Europe/Andorra	1993-12-23
+3041061	Canal de la Colilla	Canal de la Colilla		42.48333	1.58333	H	STM	AD		00				0		2349	Europe/Andorra	1993-12-23
+3041062	Canal de la Colija	Canal de la Colija		42.58333	1.65	H	STM	AD		00				0		1767	Europe/Andorra	1993-12-23
+3041063	Bosc de la Colija	Bosc de la Colija		42.58333	1.65	V	FRST	AD		00				0		1767	Europe/Andorra	1993-12-23
+3041064	Riu dels Colells	Riu dels Colells		42.53333	1.7	H	STM	AD		00				0		2357	Europe/Andorra	1993-12-23
+3041065	Circ dels Colells	Circ dels Colells		42.51667	1.7	T	CRQ	AD		00				0		2435	Europe/Andorra	1993-12-23
+3041066	Bosc dels Colells	Bosc dels Colells		42.53333	1.7	V	FRST	AD		00				0		2357	Europe/Andorra	1993-12-23
+3041067	Cortal del Coix	Cortal del Coix		42.55	1.55	S	HUTS	AD		00				0		2097	Europe/Andorra	1993-12-23
+3041068	Tartera del Coferony	Tartera del Coferony		42.5	1.45	T	SLP	AD		00				0		1840	Europe/Andorra	1993-12-23
+3041069	Coferony	Coferony		42.48333	1.45	L	LCTY	AD		00				0		1195	Europe/Andorra	1993-12-23
+3041070	Canal de les Codolles	Canal de les Codolles		42.53333	1.51667	H	STM	AD		00				0		1361	Europe/Andorra	1993-12-23
+3041071	Serrat de Codinet	Serrat de Codinet		42.51667	1.6	T	SPUR	AD		00				0		2085	Europe/Andorra	1993-12-23
+3041072	Collada del Clot Sord	Collada del Clot Sord		42.6	1.65	T	PASS	AD		00				0		2131	Europe/Andorra	1993-12-23
+3041073	Pala dels Clots d’Entinyac	Pala dels Clots d'Entinyac		42.58333	1.68333	T	SLP	AD		00				0		2294	Europe/Andorra	1993-12-23
+3041074	Tosa dels Clots de Massat	Tosa dels Clots de Massat		42.56667	1.7	T	UPLD	AD		00				0		2375	Europe/Andorra	1993-12-23
+3041075	Pala dels Clots de Massat	Pala dels Clots de Massat		42.56667	1.7	T	SLP	AD		00				0		2375	Europe/Andorra	1993-12-23
+3041076	Bassot dels Clots de Massat	Bassot dels Clots de Massat		42.56667	1.7	H	LK	AD		00				0		2375	Europe/Andorra	1993-12-23
+3041077	Clots de Massat	Clots de Massat		42.56667	1.68333	A	ADMD	AD		00				0		2340	Europe/Andorra	1993-12-23
+3041078	Clots de l’Ós	Clots de l'Os		42.58333	1.68333	A	ADMD	AD		00				0		2294	Europe/Andorra	1993-12-23
+3041079	Font dels Clots de la Llosa	Font dels Clots de la Llosa		42.61667	1.61667	H	SPNG	AD		00				0		2352	Europe/Andorra	1993-12-23
+3041080	Font dels Clots	Font dels Clots		42.55	1.71667	H	SPNG	AD		00				0		2192	Europe/Andorra	1993-12-23
+3041081	Canal del Clot del Mener	Canal del Clot del Mener		42.5	1.53333	H	STM	AD		00				0		1574	Europe/Andorra	1993-12-23
+3041082	Barranc del Clot de les Deveses	Barranc del Clot de les Deveses		42.53333	1.51667	H	STM	AD		00				0		1361	Europe/Andorra	1993-12-23
+3041083	Pic del Clot del Cavall	Pic del Clot del Cavall		42.6	1.5	T	PK	AD		00				0		1923	Europe/Andorra	1993-12-23
+3041084	Barranc del Clot d’Aixades	Barranc del Clot d'Aixades		42.56667	1.58333	H	STM	AD		00				0		1919	Europe/Andorra	1993-12-23
+3041085	Font de la Closa	Font de la Closa		42.5	1.56667	H	SPNG	AD		00				0		1776	Europe/Andorra	1993-12-23
+3041086	Pas de la Clau	Pas de la Clau		42.51667	1.61667	T	PASS	AD		00				0		2254	Europe/Andorra	1993-12-23
+3041087	Riu de Claror i Perafita	Riu de Claror i Perafita		42.5	1.55	H	STM	AD		00				0		1566	Europe/Andorra	1993-12-23
+3041088	Riu de Claror	Riu de Claror		42.47897	1.56898	H	STM	AD		00				0		2231	Europe/Andorra	2011-04-19
+3041089	Pleta de Claror	Pleta de Claror		42.48333	1.56667	L	GRAZ	AD		00				0		2231	Europe/Andorra	1993-12-23
+3041090	Camí de Claror	Cami de Claror		42.48333	1.56667	R	TRL	AD		00				0		2231	Europe/Andorra	1993-12-23
+3041091	Cabana de Claror	Cabana de Claror		42.46667	1.56667	S	HUT	AD		00				0		2365	Europe/Andorra	1993-12-23
+3041092	Claror	Claror		42.46667	1.56667	A	ADMD	AD		00				0		2365	Europe/Andorra	1993-12-23
+3041093	Riu de les Claperes	Riu de les Claperes		42.55	1.51667	H	STM	AD		00				0		1397	Europe/Andorra	1993-12-23
+3041094	Canal de les Claperes	Canal de les Claperes		42.55	1.5	H	STM	AD		00				0		1292	Europe/Andorra	1993-12-23
+3041095	Civòs	Civos		42.45	1.48333	L	LCTY	AD		00				0		1111	Europe/Andorra	1993-12-23
+3041096	Canal de la Cirera	Canal de la Cirera		42.5	1.5	H	STM	AD		00				0		1135	Europe/Andorra	1993-12-23
+3041097	Conreu de Certers	Conreu de Certers		42.48333	1.5	V	CULT	AD		00				0		1631	Europe/Andorra	1993-12-23
+3041098	Certers	Certers	Certers,Certes,Certés,Sertes	42.47468	1.50575	P	PPL	AD		06				0		1383	Europe/Andorra	2011-11-05
+3041099	Coll del Cerc	Coll del Cerc		42.46667	1.5	T	PASS	AD		00				0		1383	Europe/Andorra	1993-12-23
+3041100	Cementiri	Cementiri		42.56667	1.73333	L	LCTY	AD		00				0		2096	Europe/Andorra	1993-12-23
+3041101	Costa dell Cell	Costa dell Cell		42.48333	1.48333	T	SLP	AD		00				0		981	Europe/Andorra	1993-12-23
+3041102	Tarteres de la Cebollera	Tarteres de la Cebollera		42.63333	1.6	T	TAL	AD		00				0		2635	Europe/Andorra	1993-12-23
+3041103	Riu de la Cebollera	Riu de la Cebollera		42.61667	1.56667	H	STM	AD		00				0		2228	Europe/Andorra	1993-12-23
+3041104	Portella de la Cebollera	Portella de la Cebollera	Portella de la Cebollera	42.63333	1.6	T	PASS	AD		00				0		2635	Europe/Andorra	2011-11-05
+3041105	Pleta de la Cebollera	Pleta de la Cebollera		42.63333	1.58333	L	GRAZ	AD		00				0		2470	Europe/Andorra	1993-12-23
+3041106	Basses de la Cebollera	Basses de la Cebollera		42.63333	1.58333	H	LKS	AD		00				0		2470	Europe/Andorra	1993-12-23
+3041107	Aspres de la Cebollera	Aspres de la Cebollera		42.63333	1.58333	V	VINS	AD		00				0		2470	Europe/Andorra	1993-12-23
+3041108	Riu de les Cebes	Riu de les Cebes		42.61667	1.58333	H	STM	AD		00				0		2374	Europe/Andorra	1993-12-23
+3041109	Clot del Cavall	Clot del Cavall		42.6	1.5	T	SLP	AD		00				0		1923	Europe/Andorra	1993-12-23
+3041110	Costa del Caup	Costa del Caup		42.6	1.66667	T	SLP	AD		00				0		1858	Europe/Andorra	1993-12-23
+3041111	Solana de la Caülla	Solana de la Caulla		42.48333	1.53333	T	SLP	AD		00				0		2255	Europe/Andorra	1993-12-23
+3041112	Collada de la Caülla	Collada de la Caulla		42.48333	1.53333	T	PASS	AD		00				0		2255	Europe/Andorra	1993-12-23
+3041113	Clots de la Caülla	Clots de la Caulla		42.48333	1.53333	H	RVN	AD		00				0		2255	Europe/Andorra	1993-12-23
+3041114	Bosc de la Caülla	Bosc de la Caulla		42.48333	1.53333	V	FRST	AD		00				0		2255	Europe/Andorra	1993-12-23
+3041115	Planell de la Caubella	Planell de la Caubella		42.53333	1.48333	T	UPLD	AD		00				0		1677	Europe/Andorra	1993-12-23
+3041116	Torrent de la Cauba	Torrent de la Cauba		42.55	1.51667	H	STM	AD		00				0		1397	Europe/Andorra	1993-12-23
+3041117	Roc de la Cauba	Roc de la Cauba		42.56114	1.51506	T	RK	AD		00				0		1551	Europe/Andorra	2011-04-19
+3041118	Coll de la Cauba	Coll de la Cauba		42.58333	1.61667	T	PASS	AD		00				0		1707	Europe/Andorra	1993-12-23
+3041119	Bosc de la Cauba	Bosc de la Cauba		42.56667	1.51667	V	FRST	AD		00				0		1500	Europe/Andorra	1993-12-23
+3041120	Catolla la Guineu	Catolla la Guineu		42.46667	1.46667	L	LCTY	AD		00				0		1340	Europe/Andorra	1993-12-23
+3041121	Pic de Cataverdis	Pic de Cataverdis	Pic de Cataperdis,Pic de Cataperdís,Pic de Cataverdis	42.61667	1.46667	T	PK	AD		00				0		2442	Europe/Andorra	2011-11-05
+3041122	Roc dels Castells	Roc dels Castells		42.51667	1.55	T	RK	AD		00				0		1322	Europe/Andorra	1993-12-23
+3041123	Riu de les Castelletes	Riu de les Castelletes		42.45	1.53333	H	STM	AD		00				0		1859	Europe/Andorra	1993-12-23
+3041124	Roc de la Castelleta	Roc de la Castelleta		42.56667	1.5	T	RK	AD		00				0		1636	Europe/Andorra	1993-12-23
+3041125	Canal de la Castelleta	Canal de la Castelleta		42.53333	1.5	H	STM	AD		00				0		1357	Europe/Andorra	1993-12-23
+3041126	Bosc de la Castelleta	Bosc de la Castelleta		42.53333	1.5	V	FRST	AD		00				0		1357	Europe/Andorra	1993-12-23
+3041127	Bony de la Castelleta	Bony de la Castelleta		42.53333	1.53333	T	SPUR	AD		00				0		1521	Europe/Andorra	1993-12-23
+3041128	Font del Casteller	Font del Casteller		42.53333	1.55	H	SPNG	AD		00				0		1344	Europe/Andorra	1993-12-23
+3041129	Castell de Sant Vicenç	Castell de Sant Vicenc	Castell de Sant Vicenc,Castell de Sant Vicens,Castell de Sant Vicenç	42.49658	1.48686	S	RUIN	AD		00				0		1027	Europe/Andorra	2011-11-05
+3041130	Castell dels Moros	Castell dels Moros	Castel dels Moros La Meca,Castell dels Moros,La Meca	42.55	1.53333	T	PROM	AD	AD	00				0		1593	Europe/Andorra	2011-11-05
+3041131	Pleta del Castellar	Pleta del Castellar		42.63333	1.51667	L	GRAZ	AD		00				0		1894	Europe/Andorra	1993-12-23
+3041132	Canal del Castellar	Canal del Castellar	Canal del Castella,Canal del Castellar,Canal del Castellà	42.6	1.63333	H	STM	AD	AD	00				0		1893	Europe/Andorra	2011-11-05
+3041133	Bosc del Castellar	Bosc del Castellar		42.63333	1.51667	V	FRST	AD		00				0		1894	Europe/Andorra	1993-12-23
+3041134	Bordes del Castellar	Bordes del Castellar		42.53031	1.60873	S	HUTS	AD		00				0		2101	Europe/Andorra	2011-04-19
+3041135	Rocs de Castell	Rocs de Castell		42.46667	1.45	T	RKS	AD		00				0		1562	Europe/Andorra	1993-12-23
+3041136	Roc del Castell	Roc del Castell		42.46667	1.46667	T	RK	AD		00				0		1340	Europe/Andorra	1993-12-23
+3041137	Canal del Castell	Canal del Castell		42.58333	1.51667	H	STM	AD		00				0		1722	Europe/Andorra	1993-12-23
+3041138	Bosc del Castell	Bosc del Castell		42.58333	1.51667	V	FRST	AD		00				0		1722	Europe/Andorra	1993-12-23
+3041139	Coll de les Cases	Coll de les Cases		42.58333	1.5	T	PK	AD		00				0		1595	Europe/Andorra	1993-12-23
+3041140	Canal de les Casasses	Canal de les Casasses		42.55	1.5	H	STM	AD		00				0		1292	Europe/Andorra	1993-12-23
+3041141	Serra de Casamanya	Serra de Casamanya		42.58877	1.57163	T	RDGE	AD		00				0		2423	Europe/Andorra	2011-04-19
+3041142	Riu de Casamanya	Riu de Casamanya		42.55	1.55	H	STM	AD		00				0		2097	Europe/Andorra	1993-12-23
+3041143	Pic de Casamanya	Pic de Casamanya	Pic de Camanya,Pic de Casamanya	42.58619	1.56971	T	PK	AD		00				0		2423	Europe/Andorra	2011-11-05
+3041144	Camí de Casamanya	Cami de Casamanya		42.56667	1.55	R	TRL	AD		00				0		1996	Europe/Andorra	1993-12-23
+3041145	Casamanya	Casamanya		42.56667	1.55	A	ADMD	AD		00				0		1996	Europe/Andorra	1993-12-23
+3041146	Borda del Casadet	Borda del Casadet		42.56667	1.6	S	HUT	AD		00				0		1655	Europe/Andorra	1993-12-23
+3041147	Bordes de la Casa	Bordes de la Casa	Bordes,Bordes de la Casa	42.53333	1.61667	S	HUTS	AD	AD	00				0		2237	Europe/Andorra	2011-11-05
+3041148	Bordes de la Casa	Bordes de la Casa		42.53333	1.6	S	HUTS	AD		00				0		1888	Europe/Andorra	1993-12-23
+3041149	Pic de Carroi	Pic de Carroi		42.51667	1.5	T	PK	AD		00				0		1688	Europe/Andorra	1993-12-23
+3041150	Roc del Carret	Roc del Carret		42.56667	1.48333	T	RK	AD		00				0		1508	Europe/Andorra	1993-12-23
+3041151	Roc del Carrador	Roc del Carrador		42.56667	1.48333	T	RK	AD		00				0		1508	Europe/Andorra	1993-12-23
+3041152	Bosc del Carpider	Bosc del Carpider		42.51667	1.5	V	FRST	AD		00				0		1688	Europe/Andorra	1993-12-23
+3041153	Canal Carnissera	Canal Carnissera		42.58333	1.46667	H	STM	AD		00				0		1643	Europe/Andorra	1993-12-23
+3041154	Canal Carnissera	Canal Carnissera		42.5	1.6	H	STM	AD		00				0		2416	Europe/Andorra	1993-12-23
+3041155	Canal Carnissera	Canal Carnissera		42.65	1.55	H	RVN	AD		00				0		2181	Europe/Andorra	1993-12-23
+3041156	Roca de Carmenús	Roca de Carmenus		42.55	1.61667	T	RK	AD		00				0		2206	Europe/Andorra	1993-12-23
+3041157	Clots de Carmenús	Clots de Carmenus		42.55	1.61667	H	RVN	AD		00				0		2206	Europe/Andorra	1993-12-23
+3041158	Riu del Cardemeller	Riu del Cardemeller		42.55	1.46667	H	STM	AD		00				0		1585	Europe/Andorra	1993-12-23
+3041159	Borda del Cardago	Borda del Cardago		42.53333	1.58333	S	HUT	AD		00				0		1571	Europe/Andorra	1993-12-23
+3041160	Roca de Carcamanyà	Roca de Carcamanya		42.53333	1.56667	T	RK	AD		00				0		1418	Europe/Andorra	1993-12-23
+3041161	Barranc del Carcabanyat	Barranc del Carcabanyat		42.55	1.48333	H	STM	AD		00				0		1548	Europe/Andorra	1993-12-23
+3041162	Carboneres de Ferrer	Carboneres de Ferrer		42.48333	1.6	L	LCTY	AD		00				0		2250	Europe/Andorra	1993-12-23
+3041163	Bosc de les Carboneres	Bosc de les Carboneres		42.51667	1.51667	V	FRST	AD		00				0		1265	Europe/Andorra	1993-12-23
+3041164	Bony de les Carboneres	Bony de les Carboneres		42.56667	1.65	T	SPUR	AD		00				0		1988	Europe/Andorra	1993-12-23
+3041165	Pleta Carbona	Pleta Carbona		42.63333	1.5	L	GRAZ	AD		00				0		1979	Europe/Andorra	1993-12-23
+3041166	Planell del Carbó	Planell del Carbo		42.53333	1.48333	T	UPLD	AD		00				0		1677	Europe/Andorra	1993-12-23
+3041167	Canal de la Carbassa	Canal de la Carbassa		42.51667	1.48333	H	STM	AD		00				0		1839	Europe/Andorra	1993-12-23
+3041168	Tosa de Caraup	Tosa de Caraup		42.6	1.65	T	UPLD	AD		00				0		2131	Europe/Andorra	1993-12-23
+3041169	Planells de Caraup	Planells de Caraup		42.61667	1.65	T	UPLD	AD		00				0		2567	Europe/Andorra	1993-12-23
+3041170	Clots de Caraup	Clots de Caraup		42.61667	1.65	H	RVN	AD		00				0		2567	Europe/Andorra	1993-12-23
+3041171	Riu de Cap Torrent	Riu de Cap Torrent		42.53333	1.56667	H	STM	AD		00				0		1418	Europe/Andorra	1993-12-23
+3041172	Pont de Capigol	Pont de Capigol		42.56667	1.66667	S	BDG	AD		00				0		1938	Europe/Andorra	1993-12-23
+3041173	Font dels Capellans	Font dels Capellans		42.6	1.63333	H	SPNG	AD		00				0		1893	Europe/Andorra	1993-12-23
+3041174	Cortal del Capdevila	Cortal del Capdevila		42.53333	1.53333	S	CRRL	AD		00				0		1521	Europe/Andorra	1993-12-23
+3041175	Estany del Cap dels Pessons	Estany del Cap dels Pessons		42.51996	1.67873	H	LK	AD		00				0		2352	Europe/Andorra	2011-04-19
+3041176	Tosa del Cap del Siscaró	Tosa del Cap del Siscaro		42.58333	1.71667	T	UPLD	AD		00				0		2553	Europe/Andorra	1993-12-23
+3041177	Cap dels Clots de Massat	Cap dels Clots de Massat		42.56667	1.7	L	LCTY	AD		00				0		2375	Europe/Andorra	1993-12-23
+3041178	Collada del Cap dels Clots	Collada del Cap dels Clots		42.55	1.63333	T	PASS	AD		00				0		2336	Europe/Andorra	1993-12-23
+3041179	Cap dels Clots	Cap dels Clots		42.55	1.63333	L	LCTY	AD		00				0		2336	Europe/Andorra	1993-12-23
+3041180	Canal del Cap dels Camp	Canal del Cap dels Camp		42.55	1.53333	H	STM	AD		00				0		1593	Europe/Andorra	1993-12-23
+3041181	Clot del Cap del Maià	Clot del Cap del Maia		42.55	1.71667	H	RVN	AD		00				0		2192	Europe/Andorra	1993-12-23
+3041182	Pala del Cap de les Tallades	Pala del Cap de les Tallades		42.61667	1.55	T	SLP	AD		00				0		2007	Europe/Andorra	1993-12-23
+3041183	Planada del Cap de les Canals dels Obacs	Planada del Cap de les Canals dels Obacs		42.6	1.5	T	UPLD	AD		00				0		1923	Europe/Andorra	1993-12-23
+3041184	Cap de les Agols	Cap de les Agols		42.5	1.61667	L	LCTY	AD		00				0		2560	Europe/Andorra	1993-12-23
+3041185	Cap del Bosc de Moretó	Cap del Bosc de Moreto		42.53333	1.68333	L	LCTY	AD		00				0		2322	Europe/Andorra	1993-12-23
+3041186	Cap del Bosc dels Plans	Cap del Bosc dels Plans		42.58333	1.61667	L	LCTY	AD		00				0		1707	Europe/Andorra	1993-12-23
+3041187	Cap de la Solana del Forn	Cap de la Solana del Forn		42.53333	1.65	L	LCTY	AD		00				0		2508	Europe/Andorra	1993-12-23
+3041188	Cap de la Montada	Cap de la Montada		42.56667	1.58333	L	LCTY	AD		00				0		1919	Europe/Andorra	1993-12-23
+3041189	Tarteres del Cap de la Coma	Tarteres del Cap de la Coma		42.61667	1.48333	T	TAL	AD		00				0		2470	Europe/Andorra	1993-12-23
+3041190	Serra del Cap de la Coma	Serra del Cap de la Coma		42.61667	1.48333	T	RDGE	AD		00				0		2470	Europe/Andorra	1993-12-23
+3041191	Alt de la Capa	Alt de la Capa		42.56293	1.45424	T	PK	AD		00				0		2173	Europe/Andorra	2011-04-19
+3041192	Font de les Canyorques	Font de les Canyorques		42.58333	1.43333	H	SPNG	AD		00				0		2412	Europe/Andorra	1993-12-23
+3041193	Coves de la Canya Gran	Coves de la Canya Gran		42.48333	1.46667	S	CAVE	AD		00				0		1148	Europe/Andorra	1993-12-23
+3041194	Planell de la Canya	Planell de la Canya		42.58333	1.6	T	UPLD	AD		00				0		1828	Europe/Andorra	1993-12-23
+3041195	Bosc de la Canya	Bosc de la Canya		42.58333	1.6	V	FRST	AD		00				0		1828	Europe/Andorra	1993-12-23
+3041196	Font de Cantallops	Font de Cantallops		42.56667	1.5	H	SPNG	AD		00				0		1636	Europe/Andorra	1993-12-23
+3041197	Canal de Cantallops	Canal de Cantallops		42.56667	1.5	H	STM	AD		00				0		1636	Europe/Andorra	1993-12-23
+3041198	Roc de Canomala	Roc de Canomala		42.56667	1.68333	T	RK	AD		00				0		2340	Europe/Andorra	1993-12-23
+3041199	Santuari de Canòlic	Santuari de Canolic		42.46667	1.45	S	CH	AD		00				0		1562	Europe/Andorra	1993-12-23
+3041200	Conreu de Canòlic	Conreu de Canolic		42.48333	1.45	V	CULT	AD		00				0		1195	Europe/Andorra	1993-12-23
+3041201	Carretera de Canòlic	Carretera de Canolic		42.48333	1.46667	R	RD	AD		00				0		1148	Europe/Andorra	1993-12-23
+3041202	Canòlic	Canolic		42.46667	1.45	A	ADMD	AD		00				0		1562	Europe/Andorra	1993-12-23
+3041203	Parròquia de Canillo	Parroquia de Canillo	Canillo,Parroquia de Canillo,Parròquia de Canillo	42.58333	1.66667	A	ADM1	AD	AD	02				5067		2159	Europe/Andorra	2011-11-05
+3041204	Canillo	Canillo	Canillo,Kanil'o,ka ni e,kaniryo jiao qu,Канильо,カニーリョ教区,å¡å°¼ç•¥	42.5669	1.59556	P	PPLA	AD		02				3292		1640	Europe/Andorra	2011-11-05
+3041205	Estany de les Canals Roges	Estany de les Canals Roges		42.58333	1.71667	H	LK	AD		00				0		2553	Europe/Andorra	1993-12-23
+3041206	Cap de les Canals de Ribanelles	Cap de les Canals de Ribanelles		42.58333	1.46667	T	PK	AD		00				0		1643	Europe/Andorra	1993-12-23
+3041207	Pic de les Canals de Montmantell	Pic de les Canals de Montmantell		42.6	1.48333	T	PK	AD		00				0		2441	Europe/Andorra	1993-12-23
+3041208	Canals dels Planells de Baell	Canals dels Planells de Baell		42.5	1.6	L	LCTY	AD		00				0		2416	Europe/Andorra	1993-12-23
+3041209	Canals dels Obacs	Canals dels Obacs		42.6	1.5	H	RVN	AD		00				0		1923	Europe/Andorra	1993-12-23
+3041210	Canals del Pla de l’Ingla	Canals del Pla de l'Ingla		42.48333	1.61667	L	LCTY	AD		00				0		2217	Europe/Andorra	1993-12-23
+3041211	Canals del Maià	Canals del Maia		42.56667	1.73333	L	LCTY	AD		00				0		2096	Europe/Andorra	1993-12-23
+3041212	Canals de la Rabassa	Canals de la Rabassa		42.63333	1.56667	L	LCTY	AD		00				0		2394	Europe/Andorra	1993-12-23
+3041213	Canals de la Comarqueta	Canals de la Comarqueta		42.48333	1.61667	L	LCTY	AD		00				0		2217	Europe/Andorra	1993-12-23
+3041214	Canals de la Burna	Canals de la Burna		42.58333	1.5	L	LCTY	AD		00				0		1595	Europe/Andorra	1993-12-23
+3041215	Serra de les Canals de Falcobí	Serra de les Canals de Falcobi		42.63333	1.55	T	RDGE	AD		00				0		2053	Europe/Andorra	1993-12-23
+3041216	Canals de Falcobí	Canals de Falcobi		42.63333	1.55	L	LCTY	AD		00				0		2053	Europe/Andorra	1993-12-23
+3041217	Canals de Comascura	Canals de Comascura		42.5	1.55	L	LCTY	AD		00				0		1566	Europe/Andorra	1993-12-23
+3041218	Riu de les Canals	Riu de les Canals		42.58333	1.63333	H	STM	AD		00				0		1722	Europe/Andorra	1993-12-23
+3041219	Camí de les Canals	Cami de les Canals		42.58333	1.63333	R	TRL	AD		00				0		1722	Europe/Andorra	1993-12-23
+3041220	Bosc de les Canals	Bosc de les Canals		42.58333	1.63333	V	FRST	AD		00				0		1722	Europe/Andorra	1993-12-23
+3041221	Bosc de la Canal Llisa	Bosc de la Canal Llisa		42.56667	1.5	V	FRST	AD		00				0		1636	Europe/Andorra	1993-12-23
+3041222	Serrat de la Canal de Nicolau	Serrat de la Canal de Nicolau		42.61667	1.55	T	RDGE	AD		00				0		2007	Europe/Andorra	1993-12-23
+3041223	Solana de la Canal	Solana de la Canal		42.48333	1.43333	T	SLP	AD		00				0		1938	Europe/Andorra	1993-12-23
+3041224	Torrent de la Canadilla	Torrent de la Canadilla		42.53333	1.58333	H	STM	AD		00				0		1571	Europe/Andorra	1993-12-23
+3041225	Camps de Sispony	Camps de Sispony		42.53333	1.51667	L	LCTY	AD		00				0		1361	Europe/Andorra	1993-12-23
+3041226	Torrent dels Camps de Pardellà	Torrent dels Camps de Pardella		42.46667	1.5	H	STM	AD		00				0		1383	Europe/Andorra	1993-12-23
+3041227	Camps de Pardellà	Camps de Pardella		42.46667	1.51667	L	LCTY	AD		00				0		1985	Europe/Andorra	1993-12-23
+3041228	Camp Ramonet	Camp Ramonet		42.47397	1.53854	L	LCTY	AD		00				0		2541	Europe/Andorra	2011-04-19
+3041229	Planell de Campillar	Planell de Campillar		42.58333	1.68333	T	UPLD	AD		00				0		2294	Europe/Andorra	1993-12-23
+3041230	Fonts del Campeà	Fonts del Campea		42.51667	1.61667	H	SPNG	AD		00				0		2254	Europe/Andorra	1993-12-23
+3041231	Bosc del Campeà	Bosc del Campea		42.53333	1.63333	V	FRST	AD		00				0		2360	Europe/Andorra	1993-12-23
+3041232	Camp de Vassalló	Camp de Vassallo		42.58333	1.53333	L	LCTY	AD		00				0		1924	Europe/Andorra	1993-12-23
+3041233	Camp del Sastre	Camp del Sastre		42.45	1.53333	L	LCTY	AD		00				0		1859	Europe/Andorra	1993-12-23
+3041234	Camp del Remugar	Camp del Remugar		42.56667	1.53333	L	LCTY	AD		00				0		1669	Europe/Andorra	1993-12-23
+3041235	Camp del Cortal	Camp del Cortal		42.56667	1.5	L	LCTY	AD		00				0		1636	Europe/Andorra	1993-12-23
+3041236	Camp de la Trava	Camp de la Trava		42.56667	1.53333	L	LCTY	AD		00				0		1669	Europe/Andorra	1993-12-23
+3041237	Camp de la Llosa	Camp de la Llosa		42.56667	1.51667	L	LCTY	AD		00				0		1500	Europe/Andorra	1993-12-23
+3041238	Bosc del Camp de la Finestra	Bosc del Camp de la Finestra		42.5	1.53333	V	FRST	AD		00				0		1574	Europe/Andorra	1993-12-23
+3041239	Pedrusques del Camp de Claror	Pedrusques del Camp de Claror		42.48333	1.55	T	TAL	AD		00				0		2233	Europe/Andorra	1993-12-23
+3041240	Camp de Claror	Camp de Claror		42.46667	1.55	L	LCTY	AD		00				0		2341	Europe/Andorra	1993-12-23
+3041241	Camp Borrut	Camp Borrut		42.45	1.56667	L	LCTY	AD		00				0		2558	Europe/Andorra	1993-12-23
+3041242	Pont del Camp	Pont del Camp		42.55	1.48333	S	BDG	AD		00				0		1548	Europe/Andorra	1993-12-23
+3041243	Camí del Canal	Cami del Canal		42.51667	1.58333	H	CNL	AD		00				0		1994	Europe/Andorra	1993-12-23
+3041244	Cal Toni	Cal Toni		42.55	1.6	S	HSE	AD		00				0		2210	Europe/Andorra	1993-12-23
+3041245	Cal Serra	Cal Serra		42.46667	1.5	S	FRM	AD		00				0		1383	Europe/Andorra	1993-12-23
+3041246	Cal Ponet	Cal Ponet		42.56667	1.6	S	HSE	AD		00				0		1655	Europe/Andorra	1993-12-23
+3041247	Cal Patxeta	Cal Patxeta		42.56667	1.6	S	HSE	AD		00				0		1655	Europe/Andorra	1993-12-23
+3041248	Cal Jaumina	Cal Jaumina		42.55	1.58333	S	HSE	AD		00				0		1499	Europe/Andorra	1993-12-23
+3041249	Canal de la Calcinera	Canal de la Calcinera	Canal de la Calcinera,Canal de la Calzinera	42.53333	1.58333	H	STM	AD	AD	00				0		1571	Europe/Andorra	2011-11-05
+3041250	Cal Call	Cal Call		42.55	1.6	S	HSE	AD		00				0		2210	Europe/Andorra	1993-12-23
+3041251	Cal Borronet	Cal Borronet		42.56667	1.6	S	HSE	AD		00				0		1655	Europe/Andorra	1993-12-23
+3041252	Cal Borró	Cal Borro		42.55	1.6	S	HSE	AD		00				0		2210	Europe/Andorra	1993-12-23
+3041253	Cal Becaina	Cal Becaina		42.55	1.58333	S	HSE	AD		00				0		1499	Europe/Andorra	1993-12-23
+3041254	Cal Bartreta	Cal Bartreta		42.55	1.6	S	HSE	AD		00				0		2210	Europe/Andorra	1993-12-23
+3041255	Solà de Calaup	Sola de Calaup		42.58333	1.65	T	SLP	AD		00				0		1767	Europe/Andorra	1993-12-23
+3041256	Font de la Caitanta	Font de la Caitanta		42.48333	1.63333	H	SPNG	AD		00				0		2296	Europe/Andorra	1993-12-23
+3041257	Serrat del Caire Forc	Serrat del Caire Forc		42.53333	1.61667	T	SPUR	AD		00				0		2237	Europe/Andorra	1993-12-23
+3041258	Riu del Caire Forc	Riu del Caire Forc		42.53333	1.61667	H	STM	AD		00				0		2237	Europe/Andorra	1993-12-23
+3041259	Caire Forc	Caire Forc		42.53333	1.63333	L	LCTY	AD		00				0		2360	Europe/Andorra	1993-12-23
+3041260	Torrent dels Càcols	Torrent dels Cacols		42.56667	1.48333	H	STM	AD		00				0		1508	Europe/Andorra	1993-12-23
+3041261	Roc de la Cacarulla	Roc de la Cacarulla		42.55	1.48333	T	RK	AD		00				0		1548	Europe/Andorra	1993-12-23
+3041262	Collado de Cabris	Collado de Cabris	Collado de Cabris,Port de Cabus,Port de Cabús	42.55	1.41667	T	PASS	AD		00				0		2105	Europe/Andorra	2011-11-05
+3041263	Solana de Caborreu	Solana de Caborreu		42.43333	1.55	T	SLP	AD		00				0		2178	Europe/Andorra	1993-12-23
+3041264	Riu de Caborreu	Riu de Caborreu		42.45	1.53333	H	STM	AD		00				0		1859	Europe/Andorra	1993-12-23
+3041265	Bosc de la Cabeça	Bosc de la Cabeca		42.5	1.45	V	FRST	AD		00				0		1840	Europe/Andorra	1993-12-23
+3041266	Pleta de la Cabaneta	Pleta de la Cabaneta		42.6	1.61667	L	GRAZ	AD		00				0		2271	Europe/Andorra	1993-12-23
+3041267	Pic de la Cabaneta	Pic de la Cabaneta		42.61667	1.6	T	PK	AD		00				0		2528	Europe/Andorra	1993-12-23
+3041268	Pic de la Cabanette	Pic de la Cabanette	Cabaneta,Pic de la Cabaneta,Pic de la Cabanette	42.58333	1.73333	T	PK	AD		00				0		2378	Europe/Andorra	2011-11-05
+3041269	Bosc de la Cabanella	Bosc de la Cabanella		42.51667	1.46667	V	FRST	AD		00				0		1840	Europe/Andorra	1993-12-23
+3041270	Serra de Cabana Sorda	Serra de Cabana Sorda		42.61667	1.66667	T	RDGE	AD		00				0		2536	Europe/Andorra	1993-12-23
+3041271	Riu de Cabana Sorda	Riu de Cabana Sorda		42.6	1.68333	H	STM	AD		00				0		2089	Europe/Andorra	1993-12-23
+3041272	Pleta de Cabana Sorda	Pleta de Cabana Sorda		42.61667	1.68333	L	GRAZ	AD		00				0		2406	Europe/Andorra	1993-12-23
+3041273	Pales de Cabana Sorda	Pales de Cabana Sorda		42.61667	1.66667	T	CLF	AD		00				0		2536	Europe/Andorra	1993-12-23
+3041274	Estany de Cabana Sorda	Estany de Cabana Sorda		42.61667	1.66667	H	LK	AD		00				0		2536	Europe/Andorra	1993-12-23
+3041275	Cabana Sorda	Cabana Sorda		42.61667	1.66667	A	ADMD	AD		00				0		2536	Europe/Andorra	1993-12-23
+3041276	Font de la Cabana de l’Eucasser	Font de la Cabana de l'Eucasser		42.58333	1.61667	H	SPNG	AD		00				0		1707	Europe/Andorra	1993-12-23
+3041277	Pic de Cabayrou	Pic de Cabayrou	Cabairu,Cabairú,Pic de Cabagnau,Pic de Cabairu,Pic de Cabairú,Pic de Cabayrou	42.63333	1.46667	T	PK	AD		00				0		2324	Europe/Andorra	2011-11-05
+3041278	Font de la Ca	Font de la Ca		42.45	1.5	H	SPNG	AD		00				0		1614	Europe/Andorra	1993-12-23
+3041279	Pla de Buscalls	Pla de Buscalls	Pla de Buscalls,Pla de Busoalls	42.56667	1.65	T	UPLD	AD	AD	00				0		1988	Europe/Andorra	2011-11-05
+3041280	Serrat de la Burna	Serrat de la Burna		42.6	1.48333	T	SPUR	AD		00				0		2441	Europe/Andorra	1993-12-23
+3041281	Pic de la Burna	Pic de la Burna		42.6	1.48333	T	PK	AD		00				0		2441	Europe/Andorra	1993-12-23
+3041282	Clot de la Burna	Clot de la Burna		42.6	1.48333	T	SLP	AD		00				0		2441	Europe/Andorra	1993-12-23
+3041283	Font dels Bullidors	Font dels Bullidors		42.46667	1.45	H	SPNG	AD		00				0		1562	Europe/Andorra	1993-12-23
+3041284	Toll Bullidor	Toll Bullidor		42.58333	1.61667	L	GRAZ	AD		00				0		1707	Europe/Andorra	1993-12-23
+3041285	Barranc del Bullidor	Barranc del Bullidor		42.53333	1.71667	H	STM	AD		00				0		2400	Europe/Andorra	1993-12-23
+3041286	Roc de Bruna Roja	Roc de Bruna Roja		42.63333	1.53333	T	RK	AD		00				0		2072	Europe/Andorra	1993-12-23
+3041287	Pleta del Bruig	Pleta del Bruig		42.63333	1.5	L	GRAZ	AD		00				0		1979	Europe/Andorra	1993-12-23
+3041288	Marrades del Bruig	Marrades del Bruig		42.63333	1.5	R	TRL	AD		00				0		1979	Europe/Andorra	1993-12-23
+3041289	Basers del Bruig	Basers del Bruig		42.65	1.5	T	CLF	AD		00				0		2455	Europe/Andorra	1993-12-23
+3041290	Bruig	Bruig		42.65	1.5	T	SLP	AD		00				0		2455	Europe/Andorra	1993-12-23
+3041291	Pic del Brossós	Pic del Brossos		42.61667	1.51667	T	PK	AD		00				0		1716	Europe/Andorra	1993-12-23
+3041292	Canals del Brossós	Canals del Brossos		42.61667	1.53333	H	RVN	AD		00				0		1609	Europe/Andorra	1993-12-23
+3041293	Camí del Brossós	Cami del Brossos		42.61667	1.53333	R	TRL	AD		00				0		1609	Europe/Andorra	1993-12-23
+3041294	Cortal del Bringuer	Cortal del Bringuer		42.45	1.46667	S	CRRL	AD		00				0		935	Europe/Andorra	1993-12-23
+3041295	Cortal de Bringuer	Cortal de Bringuer		42.53333	1.53333	S	CRRL	AD		00				0		1521	Europe/Andorra	1993-12-23
+3041296	Borda del Bringuer	Borda del Bringuer		42.45	1.48333	S	HUTS	AD		00				0		1111	Europe/Andorra	1993-12-23
+3041297	Clot dels Brillons	Clot dels Brillons		42.46667	1.46667	H	RVN	AD		00				0		1340	Europe/Andorra	1993-12-23
+3041298	Brancs de la Farga	Brancs de la Farga		42.48333	1.61667	L	LCTY	AD		00				0		2217	Europe/Andorra	1993-12-23
+3041299	Tosa del Braibal	Tosa del Braibal	Tosa del Braibal,Tossal Braibal	42.50302	1.59836	T	PK	AD		00				0		2436	Europe/Andorra	2011-11-05
+3041300	Planells del Braibal	Planells del Braibal		42.51667	1.58333	T	UPLD	AD		00				0		1994	Europe/Andorra	1993-12-23
+3041301	Font del Braibal	Font del Braibal		42.51667	1.58333	H	SPNG	AD		00				0		1994	Europe/Andorra	1993-12-23
+3041302	Estany de la Bova	Estany de la Bova		42.48333	1.65	H	LK	AD		00				0		2658	Europe/Andorra	1993-12-23
+3041303	Canal de la Bova	Canal de la Bova		42.5	1.58333	H	STM	AD		00				0		1888	Europe/Andorra	1993-12-23
+3041304	Costa de Bou Mort	Costa de Bou Mort		42.46667	1.56667	T	SLP	AD		00				0		2365	Europe/Andorra	1993-12-23
+3041305	Plana del Bou	Plana del Bou		42.45	1.46667	T	UPLD	AD		00				0		935	Europe/Andorra	1993-12-23
+3041306	Cortal del Bou	Cortal del Bou		42.45	1.46667	S	HUT	AD		00				0		935	Europe/Andorra	1993-12-23
+3041307	Roc de la Botiffarra	Roc de la Botiffarra		42.48333	1.48333	T	RK	AD		00				0		981	Europe/Andorra	1993-12-23
+3041308	Col de la Botella	Col de la Botella		42.55	1.46667	T	PASS	AD		00				0		1585	Europe/Andorra	1993-12-23
+3041309	Canal del Botàs	Canal del Botas		42.55	1.58333	H	STM	AD		00				0		1499	Europe/Andorra	1993-12-23
+3041310	Canal dels Botaders	Canal dels Botaders		42.5	1.48333	H	STM	AD		00				0		1316	Europe/Andorra	1993-12-23
+3041311	Canal del Bosc Nou	Canal del Bosc Nou		42.58333	1.65	H	STM	AD		00				0		1767	Europe/Andorra	1993-12-23
+3041312	Canal del Bosc Negre	Canal del Bosc Negre		42.55	1.46667	H	STM	AD		00				0		1585	Europe/Andorra	1993-12-23
+3041313	Bosc del Coll d’Ordino	Bosc del Coll d'Ordino		42.55	1.55	A	ADMD	AD		00				0		2097	Europe/Andorra	1993-12-23
+3041314	Canal del Bosc de Coma	Canal del Bosc de Coma		42.53333	1.53333	H	STM	AD		00				0		1521	Europe/Andorra	1993-12-23
+3041315	Boscarró	Boscarro		42.55	1.46667	L	LCTY	AD		00				0		1585	Europe/Andorra	1993-12-23
+3041316	Torrent del Bosc	Torrent del Bosc		42.48333	1.45	H	STM	AD		00				0		1195	Europe/Andorra	1993-12-23
+3041317	Pla del Bosc	Pla del Bosc		42.56667	1.66667	T	UPLD	AD		00				0		1938	Europe/Andorra	1993-12-23
+3041318	Pla del Bosc	Pla del Bosc		42.55	1.6	T	UPLD	AD		00				0		2210	Europe/Andorra	1993-12-23
+3041319	Clot del Bosc	Clot del Bosc		42.43333	1.51667	T	SLP	AD		00				0		2031	Europe/Andorra	1993-12-23
+3041320	Barranc del Bosc	Barranc del Bosc		42.56667	1.58333	H	STM	AD		00				0		1919	Europe/Andorra	1993-12-23
+3041321	Boïgues de Borró	Boigues de Borro		42.55	1.6	V	CULT	AD		00				0		2210	Europe/Andorra	1993-12-23
+3041322	Pleta dels Borrecs	Pleta dels Borrecs		42.58333	1.68333	L	GRAZ	AD		00				0		2294	Europe/Andorra	1993-12-23
+3041323	Borrassica	Borrassica		42.5	1.48333	L	LCTY	AD		00				0		1316	Europe/Andorra	1993-12-23
+3041324	Pla de Borràs	Pla de Borras		42.53333	1.48333	T	UPLD	AD		00				0		1677	Europe/Andorra	1993-12-23
+3041325	Bosc del Bornal	Bosc del Bornal		42.53333	1.46667	V	FRST	AD		00				0		1846	Europe/Andorra	1993-12-23
+3041326	Pla de Bordetes	Pla de Bordetes		42.6	1.66667	T	UPLD	AD		00				0		1858	Europe/Andorra	1993-12-23
+3041327	Bordes de Ramonet	Bordes de Ramonet		42.51667	1.55	A	ADMD	AD		00				0		1322	Europe/Andorra	1993-12-23
+3041328	Canal de les Bordes	Canal de les Bordes		42.56667	1.61667	H	RVN	AD		00				0		1920	Europe/Andorra	1993-12-23
+3041329	Palanca de la Borda del Sabater	Palanca de la Borda del Sabater		42.45	1.48333	S	BDG	AD		00				0		1111	Europe/Andorra	1993-12-23
+3041330	Bosc de la Borda del Rauquet	Bosc de la Borda del Rauquet		42.6	1.63333	V	FRST	AD		00				0		1893	Europe/Andorra	1993-12-23
+3041331	Borda del Molines	Borda del Molines		42.5	1.43333	S	RUIN	AD		00				0		1654	Europe/Andorra	1993-12-23
+3041332	Borda del Ferrer Nou	Borda del Ferrer Nou		42.45	1.48333	S	RUIN	AD		00				0		1111	Europe/Andorra	1993-12-23
+3041333	Camí de la Borda del Cosp	Cami de la Borda del Cosp		42.45	1.48333	R	TRL	AD		00				0		1111	Europe/Andorra	1993-12-23
+3041334	Basera de la Borda de l’Arena	Basera de la Borda de l'Arena		42.48333	1.46667	T	CLF	AD		00				0		1148	Europe/Andorra	1993-12-23
+3041335	Borda de l’Alma	Borda de l'Alma		42.58333	1.65	S	RUIN	AD		00				0		1767	Europe/Andorra	1993-12-23
+3041336	Riu de la Bor	Riu de la Bor		42.58333	1.63333	H	STM	AD		00				0		1722	Europe/Andorra	1993-12-23
+3041337	Gorges de la Bor	Gorges de la Bor		42.55	1.58333	T	GRGE	AD		00				0		1499	Europe/Andorra	1993-12-23
+3041338	Costa del Bony Roig	Costa del Bony Roig		42.6	1.61667	T	SLP	AD		00				0		2271	Europe/Andorra	1993-12-23
+3041339	Planades del Bony Negre	Planades del Bony Negre		42.56667	1.45	T	UPLD	AD		00				0		2137	Europe/Andorra	1993-12-23
+3041340	Canal Gran del Bony de la Pica	Canal Gran del Bony de la Pica		42.5	1.46667	H	STM	AD		00				0		1678	Europe/Andorra	1993-12-23
+3041341	Obaga del Bony de la Costa	Obaga del Bony de la Costa		42.56667	1.53333	T	SLP	AD		00				0		1669	Europe/Andorra	1993-12-23
+3041342	Obaga del Bony	Obaga del Bony		42.5	1.58333	T	SLP	AD		00				0		1888	Europe/Andorra	1993-12-23
+3041343	Boïga del Bony	Boiga del Bony		42.56667	1.48333	V	CULT	AD		00				0		1508	Europe/Andorra	1993-12-23
+3041344	Boïga del Bony	Boiga del Bony		42.45	1.53333	V	CULT	AD		00				0		1859	Europe/Andorra	1993-12-23
+3041345	Canal de les Bons	Canal de les Bons		42.53333	1.58333	H	STM	AD		00				0		1571	Europe/Andorra	1993-12-23
+3041346	Canal de la Boneta	Canal de la Boneta		42.5	1.5	H	STM	AD		00				0		1135	Europe/Andorra	1993-12-23
+3041347	Pont de Bonavida	Pont de Bonavida		42.6	1.68333	S	BDG	AD		00				0		2089	Europe/Andorra	1993-12-23
+3041348	Bombal	Bombal		42.6	1.53333	L	LCTY	AD		00				0		1695	Europe/Andorra	1993-12-23
+3041349	Bosc de la Boixera	Bosc de la Boixera		42.53333	1.51667	V	FRST	AD		00				0		1361	Europe/Andorra	1993-12-23
+3041350	Canal de la Boïgueta	Canal de la Boigueta		42.56667	1.51667	H	STM	AD		00				0		1500	Europe/Andorra	1993-12-23
+3041351	Costa de les Boïgues	Costa de les Boigues		42.48333	1.46667	T	SLP	AD		00				0		1148	Europe/Andorra	1993-12-23
+3041352	Canal de les Boïgues	Canal de les Boigues		42.55	1.46667	H	STM	AD		00				0		1585	Europe/Andorra	1993-12-23
+3041353	Boïgots	Boigots		42.55	1.55	L	LCTY	AD		00				0		2097	Europe/Andorra	1993-12-23
+3041354	Font del Boïgot	Font del Boigot		42.5	1.56667	H	SPNG	AD		00				0		1776	Europe/Andorra	1993-12-23
+3041355	Canal del Boïgot	Canal del Boigot		42.5	1.55	H	STM	AD		00				0		1566	Europe/Andorra	1993-12-23
+3041356	Bosc de Boïga Plana	Bosc de Boiga Plana		42.45	1.45	V	FRST	AD		00				0		1482	Europe/Andorra	1993-12-23
+3041357	Font de la Boïga Mitgera	Font de la Boiga Mitgera		42.5	1.46667	H	SPNG	AD		00				0		1678	Europe/Andorra	1993-12-23
+3041358	Canal dels Boïgals	Canal dels Boigals		42.51667	1.5	H	STM	AD		00				0		1688	Europe/Andorra	1993-12-23
+3041359	Serrat de Boïga Gran	Serrat de Boiga Gran		42.48333	1.48333	T	SPUR	AD		00				0		981	Europe/Andorra	1993-12-23
+3041360	Font de la Boïga del Roi	Font de la Boiga del Roi		42.5	1.48333	H	SPNG	AD		00				0		1316	Europe/Andorra	1993-12-23
+3041361	Roc de Boïga Curta	Roc de Boiga Curta		42.51667	1.55	T	RK	AD		00				0		1322	Europe/Andorra	1993-12-23
+3041362	Estany Blau	Estany Blau		42.49666	1.62069	H	LK	AD		00				0		2560	Europe/Andorra	2011-04-19
+3041363	Roques Blanques	Roques Blanques		42.48333	1.48333	T	CLF	AD		00				0		981	Europe/Andorra	1993-12-23
+3041364	Rocs Blancs	Rocs Blancs		42.45	1.45	T	SLP	AD		00				0		1482	Europe/Andorra	1993-12-23
+3041365	Roca Blanca	Roca Blanca		42.56667	1.48333	T	RK	AD		00				0		1508	Europe/Andorra	1993-12-23
+3041366	La Porteille Blanche	La Porteille Blanche	La Porteille Blanche,Porteille Blanche d'Andorra,Porteille Blanche d'Andorre,Porteille Blanche d’Andorra,Porteille Blanche d’Andorre,Portella Blanca	42.5	1.73333	T	PASS	AD		00				0		2686	Europe/Andorra	2011-11-05
+3041367	Font Blanca	Font Blanca		42.65	1.53333	H	SPNG	AD		00				0		2564	Europe/Andorra	1993-12-23
+3041368	Font Blanca	Font Blanca		42.58333	1.58333	H	SPNG	AD		00				0		1993	Europe/Andorra	1993-12-23
+3041369	Canal Blanca	Canal Blanca		42.55	1.61667	H	RVN	AD		00				0		2206	Europe/Andorra	1993-12-23
+3041370	Vial Blanc	Vial Blanc		42.48333	1.5	R	RD	AD		00				0		1631	Europe/Andorra	1993-12-23
+3041371	Roc Blanc	Roc Blanc		42.48333	1.53333	T	RK	AD		00				0		2255	Europe/Andorra	1993-12-23
+3041372	Riu Blanc	Riu Blanc		42.53333	1.58333	H	STM	AD		00				0		1571	Europe/Andorra	1993-12-23
+3041373	Coll Blanc	Coll Blanc		42.52961	1.72014	T	PK	AD		00				0		2400	Europe/Andorra	2011-04-19
+3041374	Carretera de Bixessarri	Carretera de Bixessarri		42.48333	1.46667	R	RD	AD		00				0		1148	Europe/Andorra	1993-12-23
+3041375	Bixessarri	Bixessarri	Bicisarri,Bixessarri,Bixisarri,Biçisarri,Vixesarri	42.48238	1.45949	P	PPL	AD		06				0		1178	Europe/Andorra	2011-11-05
+3041376	Bissets	Bissets		42.53333	1.53333	L	LCTY	AD		00				0		1521	Europe/Andorra	1993-12-23
+3041377	Bisset	Bisset		42.55	1.53333	L	LCTY	AD		00				0		1593	Europe/Andorra	1993-12-23
+3041378	Planell del Bisbe	Planell del Bisbe		42.48333	1.58333	T	UPLD	AD		00				0		2349	Europe/Andorra	1993-12-23
+3041379	Font del Bisbe	Font del Bisbe		42.55	1.45	H	SPNG	AD		00				0		1788	Europe/Andorra	1993-12-23
+3041380	Font de la Birena	Font de la Birena		42.51667	1.51667	H	SPNG	AD		00				0		1265	Europe/Andorra	1993-12-23
+3041381	Fontanal del Besurt	Fontanal del Besurt		42.53333	1.48333	H	SPNG	AD		00				0		1677	Europe/Andorra	1993-12-23
+3041382	Roc del Bessó	Roc del Besso		42.45	1.46667	T	RK	AD		00				0		935	Europe/Andorra	1993-12-23
+3041383	Font del Bessó	Font del Besso		42.45	1.48333	H	SPNG	AD		00				0		1111	Europe/Andorra	1993-12-23
+3041384	Costa de Bescaran	Costa de Bescaran		42.43333	1.5	T	SLP	AD		00				0		1804	Europe/Andorra	1993-12-23
+3041385	Portella de Besalí	Portella de Besali		42.63333	1.55	T	PASS	AD		00				0		2053	Europe/Andorra	1993-12-23
+3041386	Pla de Besalí	Pla de Besali		42.63333	1.55	T	UPLD	AD		00				0		2053	Europe/Andorra	1993-12-23
+3041387	Pic de Besalí	Pic de Besali		42.63333	1.53333	T	PK	AD		00				0		2072	Europe/Andorra	1993-12-23
+3041388	Basers de Besalí	Basers de Besali		42.63333	1.55	T	CLF	AD		00				0		2053	Europe/Andorra	1993-12-23
+3041389	Besalí	Besali		42.63333	1.53333	A	ADMD	AD		00				0		2072	Europe/Andorra	1993-12-23
+3041390	Clot de les Berques	Clot de les Berques		42.55	1.48333	H	RVN	AD		00				0		1548	Europe/Andorra	1993-12-23
+3041391	Coma Bella	Coma Bella		42.58333	1.68333	T	VAL	AD		00				0		2294	Europe/Andorra	1993-12-23
+3041392	Riu de la Beixellosa	Riu de la Beixellosa		42.53333	1.53333	H	STM	AD		00				0		1521	Europe/Andorra	1993-12-23
+3041393	Bosc de la Beixellosa	Bosc de la Beixellosa		42.53333	1.53333	V	FRST	AD		00				0		1521	Europe/Andorra	1993-12-23
+3041394	Collada de Beixalís	Collada de Beixalis		42.53333	1.55	T	PASS	AD		00				0		1344	Europe/Andorra	1993-12-23
+3041395	Carretera Beixalís	Carretera Beixalis		42.53333	1.56667	R	RD	AD		00				0		1418	Europe/Andorra	1993-12-23
+3041396	Bosc de Beixalís	Bosc de Beixalis		42.53333	1.55	V	FRST	AD		00				0		1344	Europe/Andorra	1993-12-23
+3041397	Bordes de Beixalís	Bordes de Beixalis		42.53333	1.55	S	FRMS	AD		00				0		1344	Europe/Andorra	1993-12-23
+3041398	Beixalís	Beixalis		42.53333	1.55	A	ADMD	AD		00				0		1344	Europe/Andorra	1993-12-23
+3041399	Comes Beçoses	Comes Becoses		42.51667	1.6	H	RVN	AD		00				0		2085	Europe/Andorra	1993-12-23
+3041400	Planell dels Beços	Planell dels Becos		42.61667	1.56667	T	UPLD	AD		00				0		2228	Europe/Andorra	1993-12-23
+3041401	Bosc del Becet	Bosc del Becet		42.56667	1.53333	V	FRST	AD		00				0		1669	Europe/Andorra	1993-12-23
+3041402	Vial del Beç	Vial del Bec		42.53333	1.46667	R	TRL	AD		00				0		1846	Europe/Andorra	1993-12-23
+3041403	Solana dels Batallats	Solana dels Batallats		42.56667	1.51667	T	SLP	AD		00				0		1500	Europe/Andorra	1993-12-23
+3041404	Roc dels Batallassos	Roc dels Batallassos		42.56667	1.6	T	RK	AD		00				0		1655	Europe/Andorra	1993-12-23
+3041405	Coll del Bast	Coll del Bast		42.48333	1.48333	T	PK	AD		00				0		981	Europe/Andorra	1993-12-23
+3041406	Basses del Siscaró	Basses del Siscaro		42.58333	1.7	L	LCTY	AD		00				0		2584	Europe/Andorra	1993-12-23
+3041407	Basses dels Basers	Basses dels Basers		42.58333	1.7	L	LCTY	AD		00				0		2584	Europe/Andorra	1993-12-23
+3041408	Pales de les Basses de les Salamandres	Pales de les Basses de les Salamandres		42.61667	1.66667	T	SLP	AD		00				0		2536	Europe/Andorra	1993-12-23
+3041409	Basses de la Burna	Basses de la Burna		42.6	1.48333	T	RKS	AD		00				0		2441	Europe/Andorra	1993-12-23
+3041410	Planell de les Basses	Planell de les Basses		42.55	1.58333	T	UPLD	AD		00				0		1499	Europe/Andorra	1993-12-23
+3041411	Pla de la Bassa de les Granotes	Pla de la Bassa de les Granotes		42.58333	1.43333	T	UPLD	AD		00				0		2412	Europe/Andorra	1993-12-23
+3041412	Basers de l’Estany de Més Amunt	Basers de l'Estany de Mes Amunt		42.6	1.46667	L	LCTY	AD		00				0		2421	Europe/Andorra	1993-12-23
+3041413	Basers de Font Blanca	Basers de Font Blanca		42.65	1.55	L	LCTY	AD		00				0		2181	Europe/Andorra	1993-12-23
+3041414	Coll de Basers	Coll de Basers		42.5	1.48333	T	RDGE	AD		00				0		1316	Europe/Andorra	1993-12-23
+3041415	Baser Negre	Baser Negre		42.63333	1.46667	L	LCTY	AD		00				0		2324	Europe/Andorra	1993-12-23
+3041416	Cap del Baser de la Llonga	Cap del Baser de la Llonga		42.56667	1.51667	T	SPUR	AD		00				0		1500	Europe/Andorra	1993-12-23
+3041417	Cap del Baser	Cap del Baser		42.56667	1.51667	T	SPUR	AD		00				0		1500	Europe/Andorra	1993-12-23
+3041418	Canal de Bartreta	Canal de Bartreta		42.55	1.6	H	RVN	AD		00				0		2210	Europe/Andorra	1993-12-23
+3041419	Bosc de les Bartres	Bosc de les Bartres		42.51667	1.5	V	FRST	AD		00				0		1688	Europe/Andorra	1993-12-23
+3041420	Bosc de la Bartra	Bosc de la Bartra		42.5	1.51667	V	FRST	AD		00				0		1410	Europe/Andorra	1993-12-23
+3041421	Pont dels Barrons	Pont dels Barrons		42.61667	1.55	S	BDG	AD		00				0		2007	Europe/Andorra	1993-12-23
+3041422	Torrent del Barreró	Torrent del Barrero		42.48333	1.46667	H	STM	AD		00				0		1148	Europe/Andorra	1993-12-23
+3041423	Bosc del Barrer d’Areny	Bosc del Barrer d'Areny		42.58333	1.46667	V	FRST	AD		00				0		1643	Europe/Andorra	1993-12-23
+3041424	Barrer d’Areny	Barrer d'Areny		42.58333	1.46667	L	GRAZ	AD		00				0		1643	Europe/Andorra	1993-12-23
+3041425	Roc del Barrer	Roc del Barrer		42.55	1.53333	T	SPUR	AD		00				0		1593	Europe/Andorra	1993-12-23
+3041426	Canal del Barrer	Canal del Barrer		42.56667	1.51667	H	STM	AD		00				0		1500	Europe/Andorra	1993-12-23
+3041427	Riu de la Barraca Cremada	Riu de la Barraca Cremada		42.53333	1.7	H	STM	AD		00				0		2357	Europe/Andorra	1993-12-23
+3041428	Solà de Barra	Sola de Barra		42.58333	1.65	T	SLP	AD		00				0		1767	Europe/Andorra	1993-12-23
+3041429	Prats de la Baronia	Prats de la Baronia		42.53333	1.61667	L	GRAZ	AD		00				0		2237	Europe/Andorra	1993-12-23
+3041430	Planell de la Baronia	Planell de la Baronia		42.53333	1.61667	T	UPLD	AD		00				0		2237	Europe/Andorra	1993-12-23
+3041431	Borda de la Baronia	Borda de la Baronia		42.53333	1.61667	S	HUT	AD		00				0		2237	Europe/Andorra	1993-12-23
+3041432	Canal dels Banys	Canal dels Banys		42.53333	1.5	H	STM	AD		00				0		1357	Europe/Andorra	1993-12-23
+3041433	Bosc dels Banys	Bosc dels Banys		42.53333	1.5	V	FRST	AD		00				0		1357	Europe/Andorra	1993-12-23
+3041434	Port de Banyell	Port de Banyell		42.64218	1.5777	T	PASS	AD		00				0		2365	Europe/Andorra	2011-04-19
+3041435	Font de Banyell	Font de Banyell		42.63333	1.56667	H	SPNG	AD		00				0		2394	Europe/Andorra	1993-12-23
+3041436	Banyell	Banyell		42.63333	1.56667	L	LCTY	AD		00				0		2394	Europe/Andorra	1993-12-23
+3041437	Bosc dels Bancs	Bosc dels Bancs		42.48333	1.46667	V	FRST	AD		00				0		1148	Europe/Andorra	1993-12-23
+3041438	Riu del Bancal Vedeller	Riu del Bancal Vedeller		42.6	1.46667	H	STM	AD		00				0		2421	Europe/Andorra	1993-12-23
+3041439	Basers del Bancal Vedeller	Basers del Bancal Vedeller		42.6	1.45	T	CLF	AD		00				0		2174	Europe/Andorra	1993-12-23
+3041440	Plana del Banc	Plana del Banc		42.43333	1.5	T	UPLD	AD		00				0		1804	Europe/Andorra	1993-12-23
+3041441	Font del Baladre	Font del Baladre		42.58333	1.48333	H	SPNG	AD		00				0		1809	Europe/Andorra	1993-12-23
+3041442	Pont de la Baladosa	Pont de la Baladosa		42.6	1.68333	S	BDG	AD		00				0		2089	Europe/Andorra	1993-12-23
+3041443	Baladosa	Baladosa		42.58333	1.68333	L	LCTY	AD		00				0		2294	Europe/Andorra	1993-12-23
+3041444	Collades Baixes d’Emportona	Collades Baixes d'Emportona		42.51667	1.65	T	PASS	AD		00				0		2633	Europe/Andorra	1993-12-23
+3041445	Collades Baixes	Collades Baixes		42.5	1.63333	T	PASS	AD		00				0		2545	Europe/Andorra	1993-12-23
+3041446	Baixant	Baixant		42.55	1.48333	L	LCTY	AD		00				0		1548	Europe/Andorra	1993-12-23
+3041447	Pleta de Baix	Pleta de Baix		42.51667	1.61667	L	GRAZ	AD		00				0		2254	Europe/Andorra	1993-12-23
+3041448	Pleta de Baix	Pleta de Baix		42.48333	1.43333	L	GRAZ	AD		00				0		1938	Europe/Andorra	1993-12-23
+3041449	Estany de Baix	Estany de Baix		42.58333	1.7	H	LK	AD		00				0		2584	Europe/Andorra	1993-12-23
+3041450	Font de Baiter	Font de Baiter		42.55	1.51667	H	SPNG	AD		00				0		1397	Europe/Andorra	1993-12-23
+3041451	Port de Baiau	Port de Baiau	Port de Baiau	42.6	1.43333	T	PASS	AD		00				0		2667	Europe/Andorra	2011-11-05
+3041452	Pic de Baiau	Pic de Baiau	Pic de Baiau	42.58333	1.43333	T	PK	AD		00				0		2412	Europe/Andorra	2011-11-05
+3041453	Agulla de Baiau	Agulla de Baiau	Agulla de Baiau	42.58333	1.43333	T	PK	AD		00				0		2412	Europe/Andorra	2011-11-05
+3041454	Planells de Baell	Planells de Baell		42.48333	1.6	T	UPLD	AD		00				0		2250	Europe/Andorra	1993-12-23
+3041455	Font de Baell	Font de Baell		42.5	1.61667	H	SPNG	AD		00				0		2560	Europe/Andorra	1993-12-23
+3041456	Pleta de les Bacives	Pleta de les Bacives		42.5	1.65	L	GRAZ	AD		00				0		2542	Europe/Andorra	1993-12-23
+3041457	Serra de l’ Avier	Serra de l' Avier		42.6	1.5	T	RDGE	AD		00				0		1923	Europe/Andorra	1993-12-23
+3041458	Plana de l’ Avier	Plana de l' Avier		42.6	1.5	T	UPLD	AD		00				0		1923	Europe/Andorra	1993-12-23
+3041459	Obaga de l’ Avier	Obaga de l' Avier		42.48333	1.53333	T	SLP	AD		00				0		2255	Europe/Andorra	1993-12-23
+3041460	Costa de l’ Avier	Costa de l' Avier		42.56667	1.55	T	SLP	AD		00				0		1996	Europe/Andorra	1993-12-23
+3041461	Camí de l’ Avier	Cami de l' Avier		42.48333	1.55	R	TRL	AD		00				0		2233	Europe/Andorra	1993-12-23
+3041462	Bosc de l’ Avier	Bosc de l' Avier		42.48333	1.53333	V	FRST	AD		00				0		2255	Europe/Andorra	1993-12-23
+3041463	Torrent de l’ Aviar	Torrent de l' Aviar		42.53333	1.56667	H	STM	AD		00				0		1418	Europe/Andorra	1993-12-23
+3041464	Canal de l’ Avetar	Canal de l' Avetar		42.58333	1.65	H	STM	AD		00				0		1767	Europe/Andorra	1993-12-23
+3041465	Canal de l’ Avetar	Canal de l' Avetar		42.5	1.48333	H	STM	AD		00				0		1316	Europe/Andorra	1993-12-23
+3041466	Bosc de l’ Avetar	Bosc de l' Avetar		42.55	1.55	V	FRST	AD		00				0		2097	Europe/Andorra	1993-12-23
+3041467	Costa de Avet	Costa de Avet		42.5	1.56667	T	SLP	AD		00				0		1776	Europe/Andorra	1993-12-23
+3041468	Canal de l’ Avet	Canal de l' Avet		42.55	1.5	H	STM	AD		00				0		1292	Europe/Andorra	1993-12-23
+3041469	Costa de l’ Ave Maria	Costa de l' Ave Maria		42.61667	1.53333	T	SLP	AD		00				0		1609	Europe/Andorra	1993-12-23
+3041470	Solà de l’ Avellanet	Sola de l' Avellanet		42.58333	1.48333	T	SLP	AD		00				0		1809	Europe/Andorra	1993-12-23
+3041471	Costa dels Avellaners	Costa dels Avellaners		42.56667	1.61667	T	SLP	AD		00				0		1920	Europe/Andorra	1993-12-23
+3041472	Canal dels Avellaners	Canal dels Avellaners		42.58333	1.46667	H	RVN	AD		00				0		1643	Europe/Andorra	1993-12-23
+3041473	Coma Aubosa	Coma Aubosa		42.58333	1.5	T	SLP	AD		00				0		1595	Europe/Andorra	1993-12-23
+3041474	Riu d’ Aubinyà	Riu d' Aubinya		42.45	1.48333	H	STM	AD		00				0		1111	Europe/Andorra	1993-12-23
+3041475	Aubinyà	Aubinya	Aubinya,Aubinyà,Auvinya	42.45447	1.48761	P	PPL	AD		06				0		1159	Europe/Andorra	2011-11-05
+3041476	Aubinyà	Aubinya		42.45	1.5	A	ADMD	AD		00				0		1614	Europe/Andorra	1993-12-23
+3041477	Roc de les Aubes	Roc de les Aubes		42.51667	1.55	T	SPUR	AD		00				0		1322	Europe/Andorra	1993-12-23
+3041478	Riu de les Aubes	Riu de les Aubes		42.55	1.53333	H	STM	AD		00				0		1593	Europe/Andorra	1993-12-23
+3041479	Costa de l’ Aubell	Costa de l' Aubell		42.56667	1.53333	T	SLP	AD		00				0		1669	Europe/Andorra	1993-12-23
+3041480	Aubaderes	Aubaderes		42.5	1.48333	L	LCTY	AD		00				0		1316	Europe/Andorra	1993-12-23
+3041481	Roc de l’ Auba	Roc de l' Auba		42.56667	1.5	T	RK	AD		00				0		1636	Europe/Andorra	1993-12-23
+3041482	Canal dels Astrells	Canal dels Astrells		42.48333	1.56667	H	STM	AD		00				0		2231	Europe/Andorra	1993-12-23
+3041483	Riu de l’ Astrell	Riu de l' Astrell		42.55	1.55	H	STM	AD		00				0		2097	Europe/Andorra	1993-12-23
+3041484	Cap de l’ Astrell	Cap de l' Astrell		42.56667	1.56667	T	SPUR	AD		00				0		2089	Europe/Andorra	1993-12-23
+3041485	Bosc de l’ Astrell	Bosc de l' Astrell		42.56667	1.56667	V	FRST	AD		00				0		2089	Europe/Andorra	1993-12-23
+3041486	Canals dels Assaladors dels Pletius	Canals dels Assaladors dels Pletius		42.5	1.46667	H	STM	AD		00				0		1678	Europe/Andorra	1993-12-23
+3041487	Assaladors del Planell Gran	Assaladors del Planell Gran		42.56667	1.46667	L	LCTY	AD		00				0		1673	Europe/Andorra	1993-12-23
+3041488	Assaladors de Cabana Sorda	Assaladors de Cabana Sorda		42.6	1.66667	T	PKS	AD		00				0		1858	Europe/Andorra	1993-12-23
+3041489	Canal de l’ Assalador de Rei	Canal de l' Assalador de Rei		42.55	1.46667	H	STM	AD		00				0		1585	Europe/Andorra	1993-12-23
+3041490	Bosc de l’ Assalador	Bosc de l' Assalador		42.61667	1.65	V	FRST	AD		00				0		2567	Europe/Andorra	1993-12-23
+3041491	Bosc de l’ Assalador	Bosc de l' Assalador		42.56667	1.6	V	FRST	AD		00				0		1655	Europe/Andorra	1993-12-23
+3041492	Bosc de l’ Assalador	Bosc de l' Assalador		42.56667	1.58333	V	FRST	AD		00				0		1919	Europe/Andorra	1993-12-23
+3041493	Serra del Cap dels Aspres de Banyell	Serra del Cap dels Aspres de Banyell		42.63333	1.56667	T	MT	AD		00				0		2394	Europe/Andorra	1993-12-23
+3041494	Aspres de Banyell	Aspres de Banyell		42.63333	1.56667	L	LCTY	AD		00				0		2394	Europe/Andorra	1993-12-23
+3041495	Pic dels Aspres	Pic dels Aspres	Pic dels Aspres	42.56667	1.45	T	PK	AD		00				0	2562	2137	Europe/Andorra	2011-11-05
+3041496	Rocs de l’ Aspra	Rocs de l' Aspra		42.53333	1.53333	T	RKS	AD		00				0		1521	Europe/Andorra	1993-12-23
+3041497	Riu de l’ Aspra	Riu de l' Aspra		42.55	1.55	H	STM	AD		00				0		2097	Europe/Andorra	1993-12-23
+3041498	Clots de l’ Aspra	Clots de l' Aspra		42.51667	1.63333	H	RVN	AD		00				0		2379	Europe/Andorra	1993-12-23
+3041499	Alt de l’ Aspra	Alt de l' Aspra		42.51667	1.65	T	SLP	AD		00				0		2633	Europe/Andorra	1993-12-23
+3041500	Canals d’ Aspones	Canals d' Aspones		42.61667	1.7	H	RVN	AD		00				0		2285	Europe/Andorra	1993-12-23
+3041501	Torrent dels Aspedius	Torrent dels Aspedius		42.48333	1.53333	H	STM	AD		00				0		2255	Europe/Andorra	1993-12-23
+3041502	Comella Ascura	Comella Ascura		42.45	1.45	H	RVN	AD		00				0		1482	Europe/Andorra	1993-12-23
+3041503	Rocs de l’ Ascobet	Rocs de l' Ascobet		42.61667	1.51667	T	RKS	AD		00				0		1716	Europe/Andorra	1993-12-23
+3041504	Ascobar de Puntal	Ascobar de Puntal		42.63333	1.55	L	LCTY	AD		00				0		2053	Europe/Andorra	1993-12-23
+3041505	Canal de les Asclades	Canal de les Asclades		42.5	1.53333	H	STM	AD		00				0		1574	Europe/Andorra	1993-12-23
+3041506	Serrat de l’ Ascladella	Serrat de l' Ascladella		42.53333	1.46667	T	RDGE	AD		00				0		1846	Europe/Andorra	1993-12-23
+3041507	Fontanal de l’ Ascladella	Fontanal de l' Ascladella		42.53333	1.46667	H	SPNG	AD		00				0		1846	Europe/Andorra	1993-12-23
+3041508	Coma de l’ Ascladella	Coma de l' Ascladella		42.56667	1.48333	T	SLP	AD		00				0		1508	Europe/Andorra	1993-12-23
+3041509	Torrent dels Artics	Torrent dels Artics		42.55	1.58333	H	STM	AD		00				0		1499	Europe/Andorra	1993-12-23
+3041510	Artic de Capell	Artic de Capell		42.58333	1.6	L	LCTY	AD		00				0		1828	Europe/Andorra	1993-12-23
+3041511	Font de l’ Artic	Font de l' Artic		42.48333	1.5	H	SPNG	AD		00				0		1631	Europe/Andorra	1993-12-23
+3041512	Bony de l’ Artic	Bony de l' Artic		42.55	1.55	T	SPUR	AD		00				0		2097	Europe/Andorra	1993-12-23
+3041513	Serrat de l’ Arna Tova	Serrat de l' Arna Tova		42.58333	1.46667	T	SPUR	AD		00				0		1643	Europe/Andorra	1993-12-23
+3041514	Arna Tova	Arna Tova		42.58333	1.46667	L	LCTY	AD		00				0		1643	Europe/Andorra	1993-12-23
+3041515	Bordes de l’ Armiana	Bordes de l' Armiana		42.58333	1.6	S	HUTS	AD		00				0		1828	Europe/Andorra	1993-12-23
+3041516	Font de l’ Arinsola	Font de l' Arinsola		42.48333	1.41667	H	SPNG	AD		00				0		1920	Europe/Andorra	1993-12-23
+3041517	Riu d’ Arinsal	Riu d' Arinsal	Riu d' Arinsal,Riu d' Arinsul,Riu d’ Arinsal,Riu d’ Arinsul	42.5456	1.51523	H	STM	AD		00				0		1257	Europe/Andorra	2011-11-05
+3041518	Port d’ Arinsal	Port d' Arinsal	Port d' Arinsal,Port d’ Arinsal	42.6	1.46667	T	PASS	AD		00				0		2421	Europe/Andorra	2011-11-05
+3041519	Arinsal	Arinsal	Arinsal,ÐринÑал	42.57205	1.48453	P	PPL	AD		04				1419		1655	Europe/Andorra	2010-01-29
+3041520	Canal de Argelagosa	Canal de Argelagosa		42.51667	1.53333	H	STM	AD		00				0		1460	Europe/Andorra	1993-12-23
+3041521	Roc de l’ Areny	Roc de l' Areny		42.56667	1.6	T	PROM	AD		00				0		1655	Europe/Andorra	1993-12-23
+3041522	Rec d’ Areny	Rec d' Areny		42.58333	1.46667	H	STM	AD		00				0		1643	Europe/Andorra	1993-12-23
+3041523	Coll d’ Arenes	Coll d' Arenes		42.6	1.58333	T	PASS	AD		00				0		2461	Europe/Andorra	1993-12-23
+3041524	Bassa de l’ Arena	Bassa de l' Arena		42.51667	1.63333	H	STMH	AD		00				0		2379	Europe/Andorra	1993-12-23
+3041525	Font d’ Arduix	Font d' Arduix	Font d' Arduix,Font d’ Arduix	42.45	1.45	H	SPNG	AD		00				0		1482	Europe/Andorra	2011-11-05
+3041526	Solana d’ Arcavell	Solana d' Arcavell	Solana d' Arcabell,Solana d' Arcavell,Solana d’ Arcabell,Solana d’ Arcavell	42.43333	1.51667	T	SLP	AD		00				0		2031	Europe/Andorra	2011-11-05
+3041527	Serra d’ Arcalís	Serra d' Arcalis		42.61667	1.5	T	RDGE	AD		00				0		2390	Europe/Andorra	1993-12-23
+3041528	Roc d’ Arcalís	Roc d' Arcalis		42.63333	1.5	T	RK	AD		00				0		1979	Europe/Andorra	1993-12-23
+3041529	Riu d’ Arcalís	Riu d' Arcalis		42.63333	1.5	H	STM	AD		00				0		1979	Europe/Andorra	1993-12-23
+3041530	Portella d’ Arcalís	Portella d' Arcalis		42.61667	1.48333	T	PASS	AD		00				0		2470	Europe/Andorra	1993-12-23
+3041531	Pont d’ Arcalís	Pont d' Arcalis		42.63333	1.5	S	BDG	AD		00				0		1979	Europe/Andorra	1993-12-23
+3041532	Pic d’ Arcalís	Pic d' Arcalis		42.61575	1.4904	T	PK	AD		00				0		2431	Europe/Andorra	2011-04-19
+3041533	Feixans d’ Arcalís	Feixans d' Arcalis		42.63333	1.5	V	CULT	AD		00				0		1979	Europe/Andorra	1993-12-23
+3041534	Collades d’ Arcalís	Collades d' Arcalis		42.63333	1.51667	T	PASS	AD		00				0		1894	Europe/Andorra	1993-12-23
+3041535	Cabana d’ Arcalís	Cabana d' Arcalis		42.63333	1.5	S	HUT	AD		00				0		1979	Europe/Andorra	1993-12-23
+3041536	Basers d’ Arcalís	Basers d' Arcalis		42.61667	1.5	T	CLF	AD		00				0		2390	Europe/Andorra	1993-12-23
+3041537	Port de l’ Albeille	Port de l' Albeille	Port de l' Albeille,Port de l' Albelle,Port de l' Arbeille,Port de l' Arbella,Port de l’ Albeille,Port de l’ Albelle,Port de l’ Arbeille,Port de l’ Arbella,Porteille de l' Albelle,Porteille de l’ Albelle	42.65	1.5	T	PASS	AD		00				0		2455	Europe/Andorra	2011-11-05
+3041538	Canal de l’ Arbeguer	Canal de l' Arbeguer		42.48333	1.43333	H	STM	AD		00				0		1938	Europe/Andorra	1993-12-23
+3041539	Pont d’ Arans	Pont d' Arans		42.58333	1.51667	S	BDG	AD		00				0		1722	Europe/Andorra	1993-12-23
+3041540	Canals d’ Arans	Canals d' Arans		42.58333	1.5	H	RVN	AD		00				0		1595	Europe/Andorra	1993-12-23
+3041541	Arans	Arans	Arans	42.58226	1.51844	P	PPL	AD		05				0		1722	Europe/Andorra	2011-11-05
+3041542	Coll de la Quell	Coll de la Quell	Coll de l' Aquell,Coll de la Quell,Coll de l’ Aquell	42.48333	1.41667	T	PASS	AD		00				0		1920	Europe/Andorra	2011-11-05
+3041543	Anyós	Anyos		42.53458	1.52672	P	PPL	AD		04				0		1491	Europe/Andorra	2011-04-19
+3041544	Bosc Gran de l’ Any de la Part	Bosc Gran de l' Any de la Part		42.55	1.51667	V	FRST	AD		00				0		1397	Europe/Andorra	1993-12-23
+3041545	Planell d’ Antònia	Planell d' Antonia		42.51667	1.55	T	UPLD	AD		00				0		1322	Europe/Andorra	1993-12-23
+3041546	Ansalonga	Ansalonga	Ansalonga	42.56919	1.52285	P	PPL	AD		05				0		1500	Europe/Andorra	2011-11-05
+3041547	Serra d’ Anrodat	Serra d' Anrodat		42.61667	1.68333	T	RDGE	AD		00				0		2406	Europe/Andorra	1993-12-23
+3041548	Pic de la Coume d’Enfer	Pic de la Coume d'Enfer	Pic d' Anrodat,Pic de la Coume d'Enfer,Pic de la Coume d’Enfer,Pic d’ Anrodat	42.61667	1.68333	T	RDGE	AD		00				0		2406	Europe/Andorra	2011-11-05
+3041549	Estany d’ Anrodat	Estany d' Anrodat		42.61667	1.68333	H	LK	AD		00				0		2406	Europe/Andorra	1993-12-23
+3041550	Coll d’ Anrodat	Coll d' Anrodat	Coll d' Anrodat,Coll d’ Anrodat	42.61667	1.7	T	PASS	AD		00				0		2285	Europe/Andorra	2011-11-05
+3041551	Anrodat	Anrodat		42.61667	1.68333	A	ADMD	AD		00				0		2406	Europe/Andorra	1993-12-23
+3041552	Riu de l’ Angonella	Riu de l' Angonella		42.6	1.53333	H	STM	AD		00				0		1695	Europe/Andorra	1993-12-23
+3041553	Port de l’ Angonella	Port de l' Angonella	Port de l' Angonella,Port de l’ Angonella	42.61667	1.46667	T	PASS	AD		00				0		2442	Europe/Andorra	2011-11-05
+3041554	Pleta de l’ Angonella	Pleta de l' Angonella		42.6	1.5	L	GRAZ	AD		00				0		1923	Europe/Andorra	1993-12-23
+3041555	Pas de l’ Angonella	Pas de l' Angonella		42.6	1.5	T	PASS	AD		00				0		1923	Europe/Andorra	1993-12-23
+3041556	Estret del l’ Angonella	Estret del l' Angonella		42.6	1.5	T	GRGE	AD		00				0		1923	Europe/Andorra	1993-12-23
+3041557	Estanys de l’ Angonella	Estanys de l' Angonella		42.6	1.48333	H	LKS	AD		00				0		2441	Europe/Andorra	1993-12-23
+3041558	Basers de l’ Angonella	Basers de l' Angonella		42.61667	1.5	T	CLF	AD		00				0		2390	Europe/Andorra	1993-12-23
+3041559	Pic de les Angleves	Pic de les Angleves		42.55	1.53333	T	PK	AD		00				0		1593	Europe/Andorra	1993-12-23
+3041560	Solà de Angleva	Sola de Angleva		42.56667	1.48333	T	SLP	AD		00				0		1508	Europe/Andorra	1993-12-23
+3041561	Planell de Andreuet	Planell de Andreuet		42.51667	1.6	T	UPLD	AD		00				0		2085	Europe/Andorra	1993-12-23
+3041562	Barranc de l’ Andorrana	Barranc de l' Andorrana		42.55	1.43333	H	STM	AD		00				0		1949	Europe/Andorra	1993-12-23
+3041563	Andorra la Vella	Andorra la Vella	Ando-la-Vyey,Andora,Andora la Vela,Andora la Velja,Andora lja Vehl'ja,Andoro Malnova,Andorra,Andorra Tuan,Andorra a Vella,Andorra la Biella,Andorra la Vella,Andorra la Vielha,Andorra-a-Velha,Andorra-la-Vel'ja,Andorra-la-Vielye,Andorre-la-Vieille,Andò-la-Vyèy,Andòrra la Vièlha,an dao er cheng,andolalabeya,andwra la fyla,ΑνδόÏÏα,Ðндора ла ВелÑ,Ðндора ла Веља,Ðндора Ð»Ñ Ð’ÑльÑ,Ðндорра-ла-ВельÑ,×נדורה לה וולה,أندورا لا Ùيلا,አንዶራ ላ ቬላ,アンドラ・ラ・ヴェリャ,安é“爾城,안ë„ë¼ë¼ë² ì•¼	42.50779	1.52109	P	PPLC	AD		07				20430		1073	Europe/Andorra	2010-05-30
+3041564	Rec d’ Andorra	Rec d' Andorra		42.51667	1.51667	H	CNL	AD		00				0		1265	Europe/Andorra	1993-12-23
+3041565	Principality of Andorra	Principality of Andorra	Andora,Andoro,Andorra,Andorre,Andorrë,Andurra,Andòrra,Andóra,L'Andorre,Landoraen,Landorän,Les Vallees d' Andorre,Les Vallées d’ Andorre,L’Andorre,Principado de Andorra,Principality of Andorra,Principat d' Andorra,Principat d’ Andorra,Principaute d' Andorre,Principauté d’ Andorre,Vallees et Suzerainetes d' Andorre,Valls d' Andorra,Valls d’ Andorra,Vallées et Suzerainetés d’ Andorre,an dao er,andola,andora,andwra,antora,endora,prathes xandxrra,xandxrra,yandwrra,ΑνδόÏα,ΑνδόÏÏα,Ðндора,Ðндорра,Ô±Õ¶Õ¤Õ¸Ö€Õ¡,×נדורה,آندورا,أندورا,ئاندوررا,اندورا,انډورا,ÜܢܕܘܪÜ,अंडोरा,अनà¥à¤¡à¥‹à¤°à¤¾,à¤à¤£à¥à¤¡à¥‹à¤°à¤¾,অà§à¦¯à¦¾à¦¨à§à¦¡à§‹à¦°à¦¾,আনà§à¦¡à§‹à¦°à¦¾,à¦à¦¨à§à¦¡à§‹à¦°à¦¾,அனà¯à®Ÿà¯‹à®°à®¾,à´…à´¨àµâ€à´Ÿàµ‹à´±,ประเทศอันดอร์รา,อันดอร์รา,ອັນດà»àº¥àº²,ཨེན་ཌོ་རà¼,áƒáƒœáƒ“áƒáƒ áƒ,አንዶራ,អង់ដូររា,អានដូរ៉ា,アンドラ,安é“å°”,安é“爾,안ë„ë¼	42.5	1.5	A	PCLI	AD		00				84000		1135	Europe/Andorra	2011-11-05
+3041566	Parròquia d'Andorra la Vella	Parroquia d'Andorra la Vella	Andorra la Vella,Andorre-la-Vieille,Parroquia d'Andorra la Vella,Parròquia d'Andorra la Vella	42.5045	1.49414	A	ADM1	AD		07				24211		1236	Europe/Andorra	2008-03-17
+3041567	Canal Ampla	Canal Ampla		42.48333	1.63333	H	STM	AD		00				0		2296	Europe/Andorra	1993-12-23
+3041568	Canal Ampla	Canal Ampla		42.48333	1.6	H	STM	AD		00				0		2250	Europe/Andorra	1993-12-23
+3041569	Bosc dels Amorriadors	Bosc dels Amorriadors		42.53333	1.48333	V	FRST	AD		00				0		1677	Europe/Andorra	1993-12-23
+3041570	Solana de l’ Alzinar	Solana de l' Alzinar		42.45	1.48333	T	SLP	AD		00				0		1111	Europe/Andorra	1993-12-23
+3041571	Serrat de l’ Alzinar	Serrat de l' Alzinar		42.48333	1.46667	T	MT	AD		00				0		1148	Europe/Andorra	1993-12-23
+3041572	Canal de l’ Alzina	Canal de l' Alzina		42.5	1.5	H	STM	AD		00				0		1135	Europe/Andorra	1993-12-23
+3041573	Rocs Alts	Rocs Alts		42.56667	1.43333	T	RKS	AD		00				0		2402	Europe/Andorra	1993-12-23
+3041574	Costa de l’ Alt de la Capa	Costa de l' Alt de la Capa		42.56667	1.46667	T	SLP	AD		00				0		1673	Europe/Andorra	1993-12-23
+3041575	Pala Alta	Pala Alta		42.6	1.63333	T	CLF	AD		00				0		1893	Europe/Andorra	1993-12-23
+3041576	Terregalls de l’ Alt	Terregalls de l' Alt		42.56667	1.45	T	TAL	AD		00				0		2137	Europe/Andorra	1993-12-23
+3041577	Terregalls de l’ Alt	Terregalls de l' Alt		42.58333	1.43333	T	SPUR	AD		00				0		2412	Europe/Andorra	1993-12-23
+3041578	Font de l’ Alt	Font de l' Alt		42.56667	1.46667	H	SPNG	AD		00				0		1673	Europe/Andorra	1993-12-23
+3041579	Cresta de l’ Alt	Cresta de l' Alt		42.58333	1.45	T	SPUR	AD		00				0		2156	Europe/Andorra	1993-12-23
+3041580	Costes de l’ Alt	Costes de l' Alt		42.56667	1.45	T	SLP	AD		00				0		2137	Europe/Andorra	1993-12-23
+3041581	Canals de l’ Alt	Canals de l' Alt		42.58333	1.43333	H	RVN	AD		00				0		2412	Europe/Andorra	1993-12-23
+3041582	Canal de l’ Alt	Canal de l' Alt		42.58333	1.45	H	STM	AD		00				0		2156	Europe/Andorra	1993-12-23
+3041583	Planell dels Alls	Planell dels Alls		42.5	1.6	T	UPLD	AD		00				0		2416	Europe/Andorra	1993-12-23
+3041584	Roca de les Allaus	Roca de les Allaus		42.63333	1.53333	T	RKS	AD		00				0		2072	Europe/Andorra	1993-12-23
+3041585	Bosc de les Allaus	Bosc de les Allaus		42.53333	1.6	V	FRST	AD		00				0		1888	Europe/Andorra	1993-12-23
+3041586	Solà de l’ Allau	Sola de l' Allau		42.6	1.53333	T	SLP	AD		00				0		1695	Europe/Andorra	1993-12-23
+3041587	Planell de l’ Allau	Planell de l' Allau		42.56667	1.68333	T	UPLD	AD		00				0		2340	Europe/Andorra	1993-12-23
+3041588	Planell de l’ Allau	Planell de l' Allau		42.51667	1.58333	T	UPLD	AD		00				0		1994	Europe/Andorra	1993-12-23
+3041589	Camí de l’ Allau	Cami de l' Allau		42.58333	1.61667	R	TRL	AD		00				0		1707	Europe/Andorra	1993-12-23
+3041590	Roc de l’ Àliga	Roc de l' Aliga		42.55	1.5	T	RK	AD		00				0		1292	Europe/Andorra	1993-12-23
+3041591	Roc de l’ Àliga	Roc de l' Aliga		42.55	1.46667	T	RK	AD		00				0		1585	Europe/Andorra	1993-12-23
+3041592	Roc de l’ Àliga	Roc de l' Aliga		42.46667	1.5	T	RK	AD		00				0		1383	Europe/Andorra	1993-12-23
+3041593	Pic de l’ Àliga	Pic de l' Aliga		42.5	1.66667	T	PK	AD		00				0		2441	Europe/Andorra	1993-12-23
+3041594	Canal dels Alegrets	Canal dels Alegrets		42.5	1.48333	H	STM	AD		00				0		1316	Europe/Andorra	1993-12-23
+3041595	Pont de l’ Aldosa	Pont de l' Aldosa		42.55	1.51667	S	BDG	AD		00				0		1397	Europe/Andorra	1993-12-23
+3041596	Carretera de l’ Aldosa	Carretera de l' Aldosa		42.58333	1.63333	R	RD	AD		00				0		1722	Europe/Andorra	1993-12-23
+3041597	Pont d’ Aixovall	Pont d' Aixovall		42.48333	1.48333	S	BDG	AD		00				0		981	Europe/Andorra	1993-12-23
+3041598	Aixovall	Aixovall	Aixovall	42.46667	1.48333	P	PPL	AD		06				0		1134	Europe/Andorra	2011-11-05
+3041599	Solà d’ Aixirivall	Sola d' Aixirivall		42.46667	1.5	T	SLP	AD		00				0		1383	Europe/Andorra	1993-12-23
+3041600	Riu d’ Aixirivall	Riu d' Aixirivall		42.46667	1.5	H	STM	AD		00				0		1383	Europe/Andorra	1993-12-23
+3041601	Conreu d’ Aixirivall	Conreu d' Aixirivall		42.46667	1.5	V	CULT	AD		00				0		1383	Europe/Andorra	1993-12-23
+3041602	Carretera d’ Aixirivall	Carretera d' Aixirivall		42.45	1.48333	R	RD	AD		00				0		1111	Europe/Andorra	1993-12-23
+3041603	Bordes d’ Aixirivall	Bordes d' Aixirivall		42.45	1.51667	S	FRMS	AD		00				0		1790	Europe/Andorra	1993-12-23
+3041604	Aixirivall	Aixirivall	Aixirivali,Aixirivall,Aixirvall,Eixirivall	42.46321	1.5029	P	PPL	AD		06				0		1357	Europe/Andorra	2011-11-05
+3041605	Riu Aixec	Riu Aixec		42.58333	1.66667	H	STM	AD		00				0		2159	Europe/Andorra	1993-12-23
+3041606	Riu Aixec	Riu Aixec		42.55	1.58333	H	STM	AD		00				0		1499	Europe/Andorra	1993-12-23
+3041607	Riu d’ Aixàs	Riu d' Aixas		42.48333	1.46667	H	STM	AD		00				0		1148	Europe/Andorra	1993-12-23
+3041608	Bosc d’ Aixàs	Bosc d' Aixas		42.48333	1.46667	V	FRST	AD		00				0		1148	Europe/Andorra	1993-12-23
+3041609	Aixàs	Aixas		42.48333	1.46667	P	PPL	AD		06				0		1148	Europe/Andorra	1993-12-23
+3041610	Aixàs	Aixas		42.48333	1.46667	A	ADMD	AD		00				0		1148	Europe/Andorra	1993-12-23
+3041611	Clots d’ Aixades	Clots d' Aixades		42.58333	1.58333	H	RVN	AD		00				0		1993	Europe/Andorra	1993-12-23
+3041612	Coll de l’ Airola	Coll de l' Airola		42.48333	1.46667	T	PK	AD		00				0		1148	Europe/Andorra	1993-12-23
+3041613	Bosc de l’ Airola	Bosc de l' Airola		42.56667	1.56667	V	FRST	AD		00				0		2089	Europe/Andorra	1993-12-23
+3041614	Solà d’ Airet	Sola d' Airet		42.45	1.45	T	SLP	AD		00				0		1482	Europe/Andorra	1993-12-23
+3041615	Bosc d’ Aigües Juntes	Bosc d' Aigues Juntes		42.58333	1.46667	V	FRST	AD		00				0		1643	Europe/Andorra	1993-12-23
+3041616	Aigües Juntes	Aigues Juntes		42.58333	1.46667	H	CNFL	AD		00				0		1643	Europe/Andorra	1993-12-23
+3041617	Pont de l’ Aiguerola	Pont de l' Aiguerola		42.53333	1.61667	S	BDG	AD		00				0		2237	Europe/Andorra	1993-12-23
+3041618	Clots d’ Aigua Vella	Clots d' Aigua Vella		42.6	1.63333	H	RVN	AD		00				0		1893	Europe/Andorra	1993-12-23
+3041619	Canal d’ Aigua Vella	Canal d' Aigua Vella		42.6	1.63333	H	STM	AD		00				0		1893	Europe/Andorra	1993-12-23
+3041620	Basers d’ Aigua Vella	Basers d' Aigua Vella		42.6	1.63333	T	CLF	AD		00				0		1893	Europe/Andorra	1993-12-23
+3041621	Riu d’ Aiguarebre	Riu d' Aiguarebre		42.6	1.51667	H	STM	AD		00				0		1445	Europe/Andorra	1993-12-23
+3041622	Planell d’ Aiguarebre	Planell d' Aiguarebre		42.61667	1.51667	T	UPLD	AD		00				0		1716	Europe/Andorra	1993-12-23
+3041623	Costa d’ Aiguarebre	Costa d' Aiguarebre		42.61667	1.51667	T	SLP	AD		00				0		1716	Europe/Andorra	1993-12-23
+3041624	Costa dels Aiguaders	Costa dels Aiguaders		42.5	1.43333	T	SLP	AD		00				0		1654	Europe/Andorra	1993-12-23
+3041625	Presa d’ Aigua	Presa d' Aigua		42.5	1.58333	S	DAM	AD		00				0		1888	Europe/Andorra	1993-12-23
+3041626	Font de Les Agunes	Font de Les Agunes		42.58333	1.46667	H	SPNG	AD		00				0		1643	Europe/Andorra	1993-12-23
+3041627	Borda de les Agunes	Borda de les Agunes		42.58333	1.46667	S	FRM	AD		00				0		1643	Europe/Andorra	1993-12-23
+3041628	Planell de les Agudelles	Planell de les Agudelles		42.56667	1.55	T	UPLD	AD		00				0		1996	Europe/Andorra	1993-12-23
+3041629	Pont dels Agrels	Pont dels Agrels		42.55	1.48333	S	BDG	AD		00				0		1548	Europe/Andorra	1993-12-23
+3041630	Canal dels Agrels	Canal dels Agrels		42.55	1.48333	H	STM	AD		00				0		1548	Europe/Andorra	1993-12-23
+3041631	Serrat de l’ Agraullet	Serrat de l' Agraullet		42.53333	1.55	T	RDGE	AD		00				0		1344	Europe/Andorra	1993-12-23
+3041632	Riu de les Agols	Riu de les Agols		42.53125	1.59204	H	STM	AD		00				0		1756	Europe/Andorra	2011-04-19
+3041633	Coll dels Abòs	Coll dels Abos		42.61667	1.53333	T	PK	AD		00				0		1609	Europe/Andorra	1993-12-23
+3041634	Riu de l’ Abeurador	Riu de l' Abeurador		42.58333	1.65	H	STM	AD		00				0		1767	Europe/Andorra	1993-12-23
+3041635	Clot de les Abelletes	Clot de les Abelletes		42.53333	1.73333	T	CRQ	AD		00				0		2300	Europe/Andorra	1993-12-23
+3041636	Serra del Cap de l’ Abarsetar de Rialb	Serra del Cap de l' Abarsetar de Rialb		42.63333	1.55	T	RDGE	AD		00				0		2053	Europe/Andorra	1993-12-23
+3041637	Abarsetar de Rialb	Abarsetar de Rialb		42.65	1.55	L	LCTY	AD		00				0		2181	Europe/Andorra	1993-12-23
+3041638	Abarsetar de la Coma	Abarsetar de la Coma		42.62793	1.48624	L	LCTY	AD		07				0		2111	Europe/Andorra	2007-03-04
+3041639	Abarsetar de Ferreroles	Abarsetar de Ferreroles		42.6	1.55	L	LCTY	AD		00				0		2298	Europe/Andorra	1993-12-23
+3041640	Abarsetar d'Arcalís	Abarsetar d'Arcalis		42.62657	1.50148	L	LCTY	AD		07				0		1979	Europe/Andorra	2007-03-04
+3041641	Clots de l’ Abarsetar	Clots de l' Abarsetar		42.63333	1.55	H	RVN	AD		00				0		2053	Europe/Andorra	1993-12-23
+3041642	Abarsetar	Abarsetar		42.55	1.65	L	LCTY	AD		00				0		2432	Europe/Andorra	1993-12-23
+3041643	Pla de l’ Abarsa	Pla de l' Abarsa		42.43333	1.51667	T	UPLD	AD		00				0		2031	Europe/Andorra	1993-12-23
+3041644	Costa de l’ Abalançc	Costa de l' Abalancc		42.53333	1.53333	T	SLP	AD		00				0		1521	Europe/Andorra	1993-12-23
+3109332	Riu d’ Ós	Riu d' Os	Rio Saturia,Rio Seturia,Rio de Os,Riu d' Os,Riu d’ Ós,Río Saturia,Río Seturia,Río de Os	42.46667	1.5	H	STM	AD		00				0		1383	Europe/Andorra	2011-11-06
+3338529	Parròquia d'Escaldes-Engordany	Parroquia d'Escaldes-Engordany	Escaldes-Engordany,Parroquia d'Escaldes-Engordany,Parròquia d'Escaldes-Engordany	42.5	1.56667	A	ADM1	AD		08				16391		1776	Europe/Andorra	2008-03-17
+6463133	Eurotel	Eurotel		42.51286	1.53552	S	HTL	AD		07				0		1139	Europe/Andorra	2011-04-02
+6463689	Panorama Hotel	Panorama Hotel		42.5069	1.5361	S	HTL	AD		07				0		1350	Europe/Andorra	2007-04-13
+6463694	Roc Blanc Hotel	Roc Blanc Hotel		42.50927	1.53862	S	HTL	AD		07				0		1139	Europe/Andorra	2011-04-02
+6464858	Ahotels Prisma	Ahotels Prisma		42.5087	1.5364	S	HTL	AD		07				0		1139	Europe/Andorra	2007-04-13
+6465286	Andorra Park Hotel	Andorra Park Hotel		42.5092	1.5244	S	HTL	AD		07				0		1097	Europe/Andorra	2007-04-13
+6473225	Coma	Coma		42.559	1.533	S	HTL	AD		07				0		1514	Europe/Andorra	2007-04-17
+6473433	Magic La Massana	Magic La Massana		42.546	1.518	S	HTL	AD		07				0		1397	Europe/Andorra	2007-04-17
+6473450	Art	Art		42.5062	1.5216	S	HTL	AD		07				0		1073	Europe/Andorra	2007-04-17
+6473528	Andorra Center	Andorra Center		42.5074	1.52	S	HTL	AD		07				0		1073	Europe/Andorra	2007-04-17
+6473529	Hotel Cervol	Hotel Cervol		42.50262	1.51288	S	HTL	AD		07				0		1011	Europe/Andorra	2011-04-02
+6473530	Novotel Andorra	Novotel Andorra		42.50762	1.52734	S	HTL	AD		07				0		1205	Europe/Andorra	2011-04-03
+6473617	Roc del Sola	Roc del Sola		42.505	1.514	S	HTL	AD		07				0		1011	Europe/Andorra	2007-04-17
+6473823	L'Angel Blanc	L'Angel Blanc		42.577	1.667	S	HTL	AD		07				0		2159	Europe/Andorra	2007-04-17
+6473970	Refugi dels Isards	Refugi dels Isards		42.50616	1.5289	S	HTL	AD		07				0		1205	Europe/Andorra	2007-04-17
+6474116	Panorama	Panorama		42.507	1.535	S	HTL	AD		07				0		1350	Europe/Andorra	2007-04-17
+6474117	Font d'Argent	Font d'Argent		42.542	1.732	S	HTL	AD						0		2100	Europe/Paris	2009-09-07
+6474170	Reial Pirineus	Reial Pirineus		42.5405	1.7313	S	HTL	AD						0		2187	Europe/Paris	2009-06-28
+6474171	Hotansa Himalaya	Hotansa Himalaya		42.5405	1.7313	S	HTL	AD						0		2187	Europe/Paris	2009-09-07
+6474212	F and G La Cabana	F and G La Cabana		42.551	1.533	S	HTL	AD		07				0		1340	Europe/Andorra	2007-04-17
+6474230	Pic Maia	Pic Maia		42.5075	1.5218	S	HTL	AD		07				0		1073	Europe/Andorra	2007-04-17
+6474307	Marco Polo	Marco Polo		42.5411	1.5191	S	HTL	AD		07				0		1343	Europe/Andorra	2007-04-17
+6474384	Confort Pas de la Casa	Confort Pas de la Casa		42.5413	1.7326	S	HTL	AD						0		2187	Europe/Paris	2009-09-07
+6474447	Magic Pas	Magic Pas		42.54303	1.73188	S	HTL	AD						0		2100	Europe/Paris	2011-04-02
+6474512	Font del Marge	Font del Marge		42.5043	1.5146	S	HTL	AD		07				0		1011	Europe/Andorra	2007-04-17
+6474514	Sant Jordi	Sant Jordi		42.5043	1.5146	S	HTL	AD		07				0		1011	Europe/Andorra	2007-04-17
+6474580	AnyósPark	AnyosPark		42.53417	1.52528	S	HTL	AD		04				0		1491	Europe/Andorra	2011-04-02
+6474582	Alaska	Alaska		42.61877	1.53922	S	HTL	AD		07				0		1704	Europe/Andorra	2007-04-17
+6474659	President	President		42.502	1.512	S	HTL	AD		07				0		1011	Europe/Andorra	2007-04-17
+6474661	Himalaia Soldeu	Himalaia Soldeu		42.57647	1.66873	S	HTL	AD		07				0		2159	Europe/Andorra	2011-04-02
+6474662	Piolets	Piolets		42.5769	1.66776	S	HTL	AD		07				0		2159	Europe/Andorra	2007-04-17
+6475094	Servissim	Servissim		42.566	1.596	S	HTL	AD		07				0		1677	Europe/Andorra	2007-04-17
+6475095	Artic	Artic		42.5054	1.5183	S	HTL	AD		07				0		1073	Europe/Andorra	2007-04-17
+6475301	Magic Ski	Magic Ski		42.54557	1.51746	S	HTL	AD		07				0		1397	Europe/Andorra	2007-04-17
+6475379	Sporting	Sporting		42.5075	1.5218	S	HTL	AD		07				0		1073	Europe/Andorra	2007-04-17
+6483664	Hotel Apsis Florida	Hotel Apsis Florida		42.50811	1.52255	S	HTL	AD		07				0		1073	Europe/Andorra	2007-04-15
+6483820	Hotel Apsis Art Hotel	Hotel Apsis Art Hotel		42.5	1.51667	S	HTL	AD		07				0		1410	Europe/Andorra	2007-04-15
+6491562	Hotel Delfos	Hotel Delfos		42.50682	1.5344	S	HTL	AD		07				0		1350	Europe/Andorra	2011-04-02
+6491674	Hotel Fénix	Hotel Fenix		42.5086	1.5394	S	HTL	AD		07				0		1139	Europe/Andorra	2007-04-15
+6491682	Hotel Comtes d'Urgell	Hotel Comtes d'Urgell		42.51028	1.54099	S	HTL	AD		07				0		1139	Europe/Andorra	2011-04-02
+6492312	Ahotels Princep	Ahotels Princep		42.5073	1.5316	S	HTL	AD		07				0		1205	Europe/Andorra	2007-04-15
+6493558	Club Dorada el Tarter	Club Dorada el Tarter		42.5793	1.6414	S	HTL	AD		07				0		1727	Europe/Andorra	2007-04-14
+6493930	Residence Deusol	Residence Deusol		42.6195	1.5389	S	HTL	AD		07				0		1704	Europe/Andorra	2007-04-14
+6493995	HUSA Centric	HUSA Centric		42.5087	1.5283	S	HTL	AD		07				0		1041	Europe/Andorra	2007-04-14
+6494290	HUSA Xalet Besoli	HUSA Xalet Besoli		42.5718	1.4843	S	HTL	AD		07				0		1655	Europe/Andorra	2007-04-14
+6494345	HUSA Imperial	HUSA Imperial		42.472	1.4923	S	HTL	AD		06				0		1164	Europe/Andorra	2010-01-12
+6494491	Hotel Marco Polo	Hotel Marco Polo		42.5423	1.5174	S	HTL	AD		07				0		1397	Europe/Andorra	2007-04-14
+6494790	Husa Xalet Verdu	Husa Xalet Verdu		42.571	1.4715	S	HTL	AD		07				0		1673	Europe/Andorra	2007-04-14
+6494958	Apsis Arthotel	Apsis Arthotel		42.5072	1.5261	S	HTL	AD		07				0		1205	Europe/Andorra	2007-04-14
+6495028	Hotel Himalaia Pas	Hotel Himalaia Pas		42.5403	1.7311	S	HTL	AD						0		2187	Europe/Paris	2009-07-01
+6495053	Hotel Font	Hotel Font		42.5436	1.5117	S	HTL	AD		07				0		1257	Europe/Andorra	2007-04-14
+6495582	Hotel Austria	Hotel Austria		42.5788	1.6686	S	HTL	AD		07				0		2159	Europe/Andorra	2007-04-14
+6495704	Hotel Magic Canillo	Hotel Magic Canillo		42.5638	1.5965	S	HTL	AD		07				0		1677	Europe/Andorra	2007-04-14
+6495769	Hotel F&G La Cabana	Hotel F&G La Cabana		42.5538	1.5319	S	HTL	AD		07				0		1340	Europe/Andorra	2007-04-14
+6495790	Hotel Princesa Parc	Hotel Princesa Parc		42.574	1.4824	S	HTL	AD		07				0		1508	Europe/Andorra	2007-04-14
+6495826	Hotel Magic La Massana	Hotel Magic La Massana		42.5448	1.5163	S	HTL	AD		07				0		1257	Europe/Andorra	2007-04-14
+6497139	AHotels Confort Patagonia	AHotels Confort Patagonia		42.5627	1.4952	S	HTL	AD		07				0		1430	Europe/Andorra	2007-04-14
+6497391	Hotel Magic Andorra	Hotel Magic Andorra		42.5091	1.5297	S	HTL	AD		07				0		1041	Europe/Andorra	2007-04-14
+6497888	Ahotels Piolets Park & Spa	Ahotels Piolets Park & Spa		42.5772	1.6652	S	HTL	AD		07				0		1925	Europe/Andorra	2007-04-14
+6498453	Hotel Carlton Plaza	Hotel Carlton Plaza		42.508	1.5254	S	HTL	AD		07				0		1205	Europe/Andorra	2007-04-14
+6498890	Hotel Plaza	Hotel Plaza		42.5062	1.5296	S	HTL	AD		07				0		1205	Europe/Andorra	2007-04-14
+6499190	Hotel Ski Plaza	Hotel Ski Plaza		42.5657	1.5973	S	HTL	AD		07				0		1677	Europe/Andorra	2007-04-14
+6500087	Hesperia Andorra la Vella	Hesperia Andorra la Vella		42.5089	1.5289	S	HTL	AD		07				0		1041	Europe/Andorra	2007-04-14
+6501396	Ahotels El Serrat	Ahotels El Serrat		42.61652	1.53833	S	HTL	AD		07				0		1793	Europe/Andorra	2009-06-25
+6502212	Hotel Euro Esqui	Hotel Euro Esqui		42.5794	1.6585	S	HTL	AD		07				0		1925	Europe/Andorra	2007-04-14
+6504216	Abba Xalet Suites	Abba Xalet Suites		42.5331	1.516	S	HTL	AD		07				0		1211	Europe/Andorra	2007-04-14
+6505101	Hotel Valira	HOTEL VALIRA		42.5	1.5333	S	HTL	AD		07				0		1574	Europe/Andorra	2007-04-13
+6508304	Mercure Andorra 4	MERCURE ANDORRA 4		42.5	1.5166	S	HTL	AD		07				0		1230	Europe/Andorra	2007-04-13
+6520395	Ahotels Confort Patagonia	AHOTELS CONFORT PATAGONIA		42.5124	1.5389	S	HTL	AD		07				0		1139	Europe/Andorra	2007-04-15
+6521569	Ahotels El Serrat	AHOTELS EL SERRAT		42.5575	1.5325	S	HTL	AD		07				0		1340	Europe/Andorra	2007-04-15
+6522685	Salvia D Or Hotel	SALVIA D OR HOTEL		42.5	1.5166	S	HTL	AD		07				0		1230	Europe/Andorra	2007-04-14
+6525900	Roc De Caldes	ROC DE CALDES		42.51065	1.54706	S	HTL	AD		07				0		1227	Europe/Andorra	2011-04-03
+6529214	Metropolis	METROPOLIS		42.5166	1.55	S	HTL	AD		07				0		1498	Europe/Andorra	2007-04-14
+6529355	Diplomatic	DIPLOMATIC		42.50521	1.52715	S	HTL	AD		07				0		1205	Europe/Andorra	2011-04-02
+6529413	Eureka	EUREKA		42.50873	1.53989	S	HTL	AD		07				0		1139	Europe/Andorra	2011-04-02
+6529930	Cassany	CASSANY		42.50798	1.5248	S	HTL	AD		07				0		1073	Europe/Andorra	2011-04-02
+6942550	Andorra Palace	ANDORRA PALACE		42.50837	1.52706	S	HTL	AD		07				0		1041	Europe/Andorra	2009-06-24
+6942551	Annapurna	ANNAPURNA		42.55768	1.53255	S	HTL	AD		07				0		1340	Europe/Andorra	2009-06-24
+6942562	Bringue	BRINGUE		42.55768	1.53255	S	HTL	AD		07				0		1340	Europe/Andorra	2009-06-25
+6942564	Co Princeps	CO PRINCEPS		42.46815	1.49329	S	HTL	AD		06				0		1164	Europe/Andorra	2010-01-12
+6942568	Crowne Plaza Andorra	CROWNE PLAZA ANDORRA		42.50574	1.52002	S	HTL	AD		07				0		1073	Europe/Andorra	2009-06-25
+6942569	Diana Parc	Diana Parc		42.5444	1.5115	S	HTL	AD		07				0		1257	Europe/Andorra	2009-06-25
+6942578	Encamp	Encamp		42.53321	1.57914	S	HTL	AD						0		1571	Europe/Andorra	2009-06-25
+6942579	Diana parc	Diana parc		42.61886	1.53939	S	HTL	AD		07				0		1704	Europe/Andorra	2009-06-25
+6942582	Font d'argent Canillo	Font d'argent Canillo		42.57086	1.60782	S	HTL	AD						0		1655	Europe/Andorra	2011-04-03
+6942589	GRAU ROIG	GRAU ROIG		42.5327	1.70116	S	HTL	AD						0		2357	Europe/Andorra	2009-06-25
+6942604	Husa Patagonia	Husa Patagonia		42.57139	1.48566	S	HTL	AD		07				0		1655	Europe/Andorra	2009-06-26
+6942646	Ibis Andorra	Ibis Andorra		42.51252	1.55059	S	HTL	AD		07				0		1498	Europe/Andorra	2011-04-03
+6942647	Lake placid	Lake placid		42.54119	1.73333	S	HTL	AD						0		2187	Europe/Paris	2009-06-28
+6942648	Les closes	Les closes		42.5087	1.53993	S	HTL	AD		07				0		1139	Europe/Andorra	2009-06-28
+6942649	L Isard	L Isard		42.50775	1.52288	S	HTL	AD		07				0		1073	Europe/Andorra	2009-06-28
+6942650	Paris	Paris		42.528	1.56927	S	HTL	AD						0		1418	Europe/Andorra	2009-06-28
+6942651	Pere D Urg	Pere D Urg		42.5347	1.58012	S	HTL	AD						0		1309	Europe/Andorra	2009-06-28
+6942667	Prat de les mines	Prat de les mines		42.59406	1.52684	S	HTL	AD		07				0		1695	Europe/Andorra	2009-06-28
+6942674	Rialb	Rialb		42.61886	1.53939	S	HTL	AD		07				0		1704	Europe/Andorra	2009-06-28
+6942675	Rutllan	Rutllan		42.54738	1.51345	S	HTL	AD		04				0		1257	Europe/Andorra	2009-06-28
+6942676	Sant Eloi	Sant Eloi		42.45793	1.48717	S	HTL	AD						0		1159	Europe/Madrid	2011-04-02
+6942677	Shusski	Shusski		42.5338	1.58577	S	HTL	AD						0		1490	Europe/Andorra	2009-06-28
+6942678	Solana	Solana		42.58099	1.5193	S	HTL	AD						0		1722	Europe/Andorra	2009-06-28
+6942680	Somriu Comapedrosa	Somriu Comapedrosa		42.58099	1.5193	S	HTL	AD						0		1722	Europe/Andorra	2009-06-28
+6942681	Somriu Galanthus	Somriu Galanthus		42.5769	1.66776	S	HTL	AD		07				0		2159	Europe/Andorra	2009-06-28
+6942682	Les Terres	Les Terres		42.57916	1.63023	S	HTL	AD						0		1722	Europe/Andorra	2011-04-02
+6942683	Somriu Segle Xx	SOMRIU SEGLE XX		42.58118	1.63827	S	HTL	AD						0		1727	Europe/Andorra	2009-09-08
+6942684	Somriu Solana Del Ransol	SOMRIU SOLANA DEL RANSOL		42.58002	1.64432	S	HTL	AD		07				0		1737	Europe/Andorra	2009-06-28
+6942685	Somriu Tivoli	SOMRIU TIVOLI		42.5076	1.53223	S	HTL	AD		07				0		1205	Europe/Andorra	2009-06-28
+6942686	Somriu Vall Ski	Somriu Vall Ski		42.57723	1.66752	S	HTL	AD		07				0		2159	Europe/Andorra	2009-06-28
+6942696	Sport	Sport		42.57688	1.66688	S	HTL	AD		07				0		2159	Europe/Andorra	2009-06-29
+6942697	Sport Hermitage	SPORT HERMITAGE		42.57727	1.6672	S	HTL	AD		07				0		2159	Europe/Andorra	2009-06-29
+6942698	Sport Village	Sport Village		42.57688	1.66688	S	HTL	AD		07				0		2159	Europe/Andorra	2009-06-29
+6942740	APARTAMENTS TURISTICS GLAÇ	APARTAMENTS TURISTICS GLAC		42.58	1.64623	S	HTL	AD		07				0		1737	Europe/Andorra	2009-06-30
+6942759	Aparthotel Cosmos	Aparthotel Cosmos		42.51	1.541	S	HTL	AD		07				0		1139	Europe/Andorra	2009-06-30
+6942761	Carlemany	Carlemany		42.509	1.538	S	HTL	AD		07				0		1139	Europe/Andorra	2009-06-30
+6942762	Cims Andorra	Cims Andorra		42.5085	1.5307	S	HTL	AD		07				0		1041	Europe/Andorra	2009-06-30
+6942764	Folch	Folch		42.471	1.493	S	HTL	AD		06				0		1164	Europe/Andorra	2010-01-12
+6942766	Hotel La Solana	Hotel La Solana		42.533	1.593	S	HTL	AD		07				0		1756	Europe/Andorra	2009-09-07
+6942767	Phoebus	Phoebus		42.54103	1.72985	S	HTL	AD						0		2187	Europe/Paris	2009-06-30
+6942768	Pol	Pol		42.465	1.491	S	HTL	AD		06				0		1045	Europe/Andorra	2009-06-30
+6942770	Subira	Subira		42.632	1.5	S	HTL	AD						0		1979	Europe/Andorra	2009-06-30
+6942771	Vip Plus	Vip Plus		42.535	1.588	S	HTL	AD						0		1490	Europe/Andorra	2009-06-30
+6942793	Acta Arthotel	Acta Arthotel		42.50728	1.52609	S	HTL	AD		07				0		1205	Europe/Andorra	2009-07-01
+6942794	Ahotels Patagonia Austral	Ahotels Patagonia Austral		42.57246	1.48436	S	HTL	AD		07				0		1655	Europe/Andorra	2009-07-01
+6942796	Del Tarter	Del Tarter		42.58035	1.64893	S	HTL	AD		07				0		1737	Europe/Andorra	2009-07-01
+6942797	Hotel Llop Gris	Hotel Llop Gris		42.57804	1.64845	S	HTL	AD		07				0		1737	Europe/Andorra	2009-07-01
+6948955	Apartamentos Xixerella	APARTAMENTOS XIXERELLA		42.55309	1.48746	S	HTL	AD		04				0		1520	Europe/Andorra	2009-09-07
+6948956	Apartaments Gla	APARTAMENTS GLA		42.56	1.67396	S	HTL	AD						0		1963	Europe/Andorra	2009-09-07
+6948957	Boston	Boston		42.6083	1.5394	S	HTL	AD		07				0		1821	Europe/Andorra	2009-09-07
+6948958	Coma Bella	COMA BELLA		42.46487	1.49115	S	HTL	AD		06				0		1045	Europe/Andorra	2009-09-07
+6948959	Confort Soldeu	CONFORT SOLDEU		42.5769	1.66776	S	HTL	AD		07				0		2159	Europe/Andorra	2009-09-07
+6948960	Coray	CORAY		42.535	1.584	S	HTL	AD						0		1490	Europe/Andorra	2009-09-07
+6948963	Del Clos	Del Clos		42.6187	1.5392	S	HTL	AD		07				0		1704	Europe/Andorra	2009-09-07
+6948965	El Xalet	EL XALET		42.58035	1.64892	S	HTL	AD		07				0		1737	Europe/Andorra	2009-09-07
+6948966	Els Llacs	ELS LLACS		42.56012	1.68173	S	HTL	AD						0		2094	Europe/Andorra	2009-09-07
+6948967	Els Meners	ELS MENERS		42.566	1.596	S	HTL	AD		07				0		1677	Europe/Andorra	2009-09-07
+6948968	Espel	Espel		42.509	1.542	S	HTL	AD		07				0		1227	Europe/Andorra	2009-09-07
+6948969	Euro Ski	Euro Ski		42.6187	1.5392	S	HTL	AD		07				0		1704	Europe/Andorra	2009-09-07
+6948970	Guillen	Guillen		42.536	1.583	S	HTL	AD						0		1309	Europe/Andorra	2009-09-07
+6948971	Hotansa Austria	HOTANSA AUSTRIA		42.56012	1.68173	S	HTL	AD						0		2094	Europe/Andorra	2009-09-07
+6948972	Iglu	IGLU		42.53263	1.70035	S	HTL	AD						0		2357	Europe/Andorra	2009-09-07
+6948973	Kandahar	KANDAHAR		42.5413	1.7325	S	HTL	AD						0		2187	Europe/Paris	2009-09-07
+6948974	L Obaga Blanca	L OBAGA BLANCA		42.5617	1.60352	S	HTL	AD						0		1969	Europe/Andorra	2009-09-07
+6948975	Montecarlo	MONTECARLO		42.528	1.569	S	HTL	AD						0		1418	Europe/Andorra	2009-09-07
+6948976	Naudi	Naudi		42.6187	1.5392	S	HTL	AD		07				0		1704	Europe/Andorra	2009-09-07
+6948977	Nordic	NORDIC		42.58035	1.64892	S	HTL	AD		07				0		1737	Europe/Andorra	2009-09-07
+6948991	Hotel Oros	Hotel Oros		42.54564	1.73176	S	HTL	AD						0		2100	Europe/Paris	2011-04-03
+6948993	Palome	Palome		42.56148	1.49741	S	HTL	AD		07				0		1430	Europe/Andorra	2009-09-08
+6948995	Paradis Blanc	PARADIS BLANC		42.54152	1.73378	S	HTL	AD						0		2385	Europe/Paris	2009-09-08
+6948996	Rutllan Xalet De Muntanya	RUTLLAN XALET DE MUNTANYA		42.5479	1.51319	S	HTL	AD		04				0		1257	Europe/Andorra	2009-09-08
+6948997	Sant Bernat Apartments	SANT BERNAT APARTMENTS		42.56609	1.5967	S	HTL	AD		07				0		1677	Europe/Andorra	2009-09-08
+6948998	Solana de ransol	Solana de ransol		42.57831	1.6352	S	HTL	AD						0		1727	Europe/Andorra	2009-09-08
+6948999	Soldeu Maistre	Soldeu Maistre		42.5769	1.66776	S	HTL	AD		07				0		2159	Europe/Andorra	2009-09-08
+6949002	St Gothard	ST GOTHARD		42.5723	1.484	S	HTL	AD		07				0		1655	Europe/Andorra	2009-09-08
+6949004	Univers	Univers		42.53647	1.58195	S	HTL	AD						0		1309	Europe/Andorra	2009-09-08
+6949005	Velvet	Velvet		42.7467	1.7081	S	HTL	AD						0		1563	Europe/Paris	2009-09-08
+6949010	Xalet Montana	Xalet Montana		42.57701	1.66627	S	HTL	AD		07				0		1925	Europe/Andorra	2009-09-08
+7114070	andorra magica	andorra magica		42.50727	1.52202	S	HTL	AD		07				0		1073	Europe/Andorra	2009-12-02
+7284857	Apartamentos L Angel Blanc	Apartamentos L Angel Blanc		42.577	1.667	S	HTL	AD		07				0		2159	Europe/Andorra	2010-04-01
+7284858	Apartamentos Giberga	Apartamentos Giberga		42.552	1.51081	S	HTL	AD						0		1400	Europe/Andorra	2010-04-01
+7284859	Aparthotel l'Alba	Aparthotel l'Alba		42.5787	1.6532	S	HTL	AD		02				0		1767	Europe/Andorra	2010-04-01
+7284866	Magic Canillo Apartments	Magic Canillo Apartments		42.5669	1.60041	S	HTL	AD		02				0		1655	Europe/Andorra	2010-04-01
+7284867	Apartaments Sant Romà	Apartaments Sant Roma		42.5736	1.48311	S	HTL	AD						0		1508	Europe/Andorra	2010-04-01
+7284869	Saporo	Saporo		42.5432	1.73327	S	HTL	AD		03				0		2100	Europe/Paris	2010-04-01
+7284872	Aparthotel Casa Vella	Aparthotel Casa Vella		42.5537	1.53215	S	HTL	AD						0		1340	Europe/Andorra	2010-04-01
+7284874	Caldea Centre Termolùdic d' Andorra	Caldea Centre Termoludic d' Andorra		42.5117	1.5367	S	HTL	AD		07				0		1139	Europe/Andorra	2010-04-01
+7284875	Comabella Hotel	Comabella Hotel		42.5	1.5166	S	HTL	AD		07				0		1230	Europe/Andorra	2010-04-01
+7284915	Hotel Galanthus	Hotel Galanthus		42.5829	1.66268	S	HTL	AD		02				0		1925	Europe/Andorra	2010-04-02
+7284920	Hotel Cims Pas	Hotel Cims Pas		42.5428	1.73479	S	HTL	AD		03				0		2230	Europe/Paris	2010-04-02
+7284921	Hotel Cims Pas de La Casa	Hotel Cims Pas de La Casa		42.5428	1.73479	S	HTL	AD		03				0		2230	Europe/Paris	2010-04-02
+7284925	Hotel del Clos	Hotel del Clos		42.5786	1.65121	S	HTL	AD		02				0		1767	Europe/Andorra	2010-04-02
+7284926	Hotel Erts	Hotel Erts		42.5454	1.51909	S	HTL	AD		07				0		1397	Europe/Andorra	2010-04-02
+7284927	Hotel Font De Ferro	Hotel Font De Ferro		42.5902	1.52436	S	HTL	AD						0		1525	Europe/Andorra	2010-04-02
+7284952	Magic Ski La Massana Hotel	Magic Ski La Massana Hotel		42.5457	1.51838	S	HTL	AD		07				0		1397	Europe/Andorra	2010-04-04
+7284953	Hotel Metropolis	Hotel Metropolis		42.5102	1.54086	S	HTL	AD		07				0		1139	Europe/Andorra	2010-04-04
+7284954	Hotel Palarine	Hotel Palarine		42.5763	1.5187	S	HTL	AD						0		1722	Europe/Andorra	2010-04-04
+7284955	Hotel Paris Londres	Hotel Paris Londres		42.5087	1.54083	S	HTL	AD		07				0		1139	Europe/Andorra	2010-04-04
+7284956	Hotel Parma	Hotel Parma		42.5432	1.73297	S	HTL	AD		03				0		2100	Europe/Paris	2010-04-04
+7284957	Residència Daina	Residencia Daina		42.5615	1.49775	S	HTL	AD						0		1430	Europe/Andorra	2010-04-04
+7284958	Hotel Roc del Castell	Hotel Roc del Castell		42.566	1.596	S	HTL	AD		07				0		1677	Europe/Andorra	2010-04-04
+7284959	Hotel Siracusa	Hotel Siracusa		42.509	1.54305	S	HTL	AD		07				0		1227	Europe/Andorra	2010-04-04
+7284960	Somriu Hotel Refugi dels Isards	Somriu Hotel Refugi dels Isards		42.5433	1.73494	S	HTL	AD		03				0		2230	Europe/Paris	2010-04-04
+7284961	Sport Hotel Hermitage & Spa	Sport Hotel Hermitage & Spa		42.5763	1.66991	S	HTL	AD		07				0		2159	Europe/Andorra	2010-04-04
+7284962	Hotel Tristaina	Hotel Tristaina		42.6189	1.53714	S	HTL	AD						0		1704	Europe/Andorra	2010-04-04
+7287697	Hotel Montane	Hotel Montane		42.5454	1.51909	S	HTL	AD		07				0		1397	Europe/Andorra	2010-04-06
+7287698	Hotel Pitiusa	Hotel Pitiusa		42.5089	1.53258	S	HTL	AD		07				0		1041	Europe/Andorra	2010-04-06
+7287699	Hotel Príncep	Hotel Princep		42.5087	1.54083	S	HTL	AD		07				0		1139	Europe/Andorra	2010-04-06
+7287700	Hotel I Termes Carlemany	Hotel I Termes Carlemany		42.5092	1.54409	S	HTL	AD		07				0		1227	Europe/Andorra	2010-04-06
+7287701	Hotel Viena	Hotel Viena		42.5069	1.52004	S	HTL	AD		07				0		1073	Europe/Andorra	2010-04-06
+7302102	La Margineda	La Margineda		42.484	1.49242	P	PPL	AD		07				0		1353	Europe/Andorra	2010-05-26
+7730819	Andorra la Vella Heliport	Andorra la Vella Heliport	ALV	42.5005	1.51712	S	AIRH	AD						0		1073	Europe/Andorra	2011-03-17
+7733010	Grau Roig	Grau Roig		42.53251	1.69923	P	PPL	AD						0		2204	Europe/Andorra	2011-04-07
+251130	WÄdÄ« Siqattah	Wadi Siqattah	Wadi Siqatta,Wadi Siqattah,WÄdÄ« Siqatta,WÄdÄ« Siqattah	25.6225	56.2225	H	WAD	AE		00				0		99	Asia/Dubai	2011-11-06
+286280	Suhaylah	Suhaylah	Suhaylah,Suheila	24.80388	56.19449	P	PPL	AE		02				0		238	Asia/Dubai	2011-11-06
+288716	WÄdÄ« al Bīḩ	Wadi al Bih	Wadi al Bih,WÄdÄ« al Bīḩ	25.77361	56.04389	H	WAD	AE		05				0		49	Asia/Dubai	2011-11-06
+290399	Zuyūd	Zuyud	Zuyud,Zuyūd	25.2	56.21667	L	TRB	AE		04				0		223	Asia/Dubai	2011-11-06
+290400	Z̧uwayhir	Zuwayhir	Dhawaihir,Duwaihir,Zuwayhir,Z̧uwayhir	23.28333	53.2	P	PPL	AE	AE	01				0		170	Asia/Dubai	2011-11-06
+290401	Z̧uwayhir	Zuwayhir	Dhuwaiher,Zuwayhir,Zuweihir,Z̧uwayhir	23.13916	53.6934	P	PPL	AE		01				0		104	Asia/Dubai	2011-11-06
+290402	Zuwayghir	Zuwayghir	Zuwaighar,Zuwayghir	24.08333	55.26667	H	WLL	AE	AE	01				0		167	Asia/Dubai	2011-11-06
+290403	WÄdÄ« Zuqaybah	Wadi Zuqaybah	Wadi Zuqaybah,WÄdÄ« Zuqaybah	25.40753	56.12592	H	WAD	AE		04				0		383	Asia/Dubai	2011-11-06
+290404	Ţawī Z̧ulaymah	Tawi Zulaymah	Dhalaima,Dulaima,Tawi Dhalaima,Tawi Dhelaimah,Tawi Dulaymah,Tawi Zeleimah,Tawi Zulaymah,Ţawī Dhalaima,Ţawī Dulaymah,Ţawī Z̧ulaymah	24.67083	55.53083	H	WLLQ	AE	AE	01				0		208	Asia/Dubai	2011-11-06
+290405	Z̧ulaymah	Zulaymah	Dulaymah,Zulaymah,Z̧ulaymah	24.65	55.53333	T	TRGD	AE	AE	03				0		230	Asia/Dubai	2011-11-06
+290406	Ruqq az Zukum	Ruqq az Zukum	Rak al Lakum,Rak az Zakum,Rig az Zakum,Ruqq az Zaqqum,Ruqq az Zaqqūm,Ruqq az Zukum	24.8	53.7	H	SHOL	AE	AE	01				0		-9999	Asia/Dubai	2011-11-06
+290407	Zubyah	Zubyah	Zabia,Zubyah	24.96667	55.06667	T	SAND	AE	AE	03				0		20	Asia/Dubai	2011-11-06
+290408	Jabal al ‘Azab	Jabal al `Azab	Jabal Azab,Jabal Zubb al `Azab,Jabal Zubb al ‘Azab,Jabal al `Azab,Jabal al ‘Azab	25.16139	55.83861	T	DUNE	AE		06				0		275	Asia/Dubai	2011-11-06
+290409	ZubÄrah	Zubarah	Zubara,Zubarah,ZubÄra,ZubÄrah	25.40487	56.35971	P	PPL	AE		04				0		-9999	Asia/Dubai	2011-11-06
+290410	ZirkÅ«h	Zirkuh	Az Zarqa',Az ZarqÄ’,Jazirat Zarka,Jazirat Zirku,Jaztal Zarakkuh,Jaztal ZarakkÅ«h,JazÄ«rat ZarkÄ,JazÄ«rat ZÄ«rkÅ«,Jezirat Zirko,JezÄ«rat Zirko,Zarakkawh,Zarakkuh,Zarqa,Zirko Island,Zirkuh,ZirkÅ«h	24.88417	53.07222	T	ISL	AE	AE	01				0		161	Asia/Dubai	2011-11-06
+290411	Zirđah	Zira`ah	Zira`ah,Zirđah	24.06667	55.53333	T	SAND	AE		01				0		182	Asia/Dubai	2011-11-06
+290412	Zirđ	Zira`	Zira`,Zirđ	23.76822	54.20993	H	WLL	AE		01				0		116	Asia/Dubai	2011-11-06
+290413	Sabkhat ZinÄd	Sabkhat Zinad	Sabkhat Zinad,Sabkhat ZinÄd	24.48293	55.22135	H	SBKH	AE		01				0		145	Asia/Dubai	2011-11-06
+290414	ZinÄd	Zinad	Zinad,ZinÄd	24.5	55.23333	T	SAND	AE		01				0		151	Asia/Dubai	2011-11-06
+290415	Zimmat Ḩalamah	Zimmat Halamah	Zimmat Halamah,Zimmat Ḩalamah	24.13333	55.48333	T	DUNE	AE		01				0		187	Asia/Dubai	2011-11-06
+290416	Zimmat ‘Ankah	Zimmat `Ankah	Zimmat `Ankah,Zimmat ‘Ankah	24.16667	55.33333	T	DUNE	AE		01				0		173	Asia/Dubai	2011-11-06
+290417	WÄdÄ« Zikt	Wadi Zikt	Wadi Zikt,WÄdÄ« Zikt	25.52536	56.31864	H	WAD	AE		04				0		140	Asia/Dubai	2011-11-06
+290418	Jabal Zikt	Jabal Zikt	Jabal Zikt	25.51435	56.31373	T	HLL	AE		04				0		285	Asia/Dubai	2011-11-06
+290419	Zikt	Zikt	Zikt	25.5118	56.32328	P	PPL	AE		04				0		41	Asia/Dubai	2011-11-06
+290420	Ziffah	Ziffah	Ziffah	25.02385	56.28954	V	CULT	AE		04				0		99	Asia/Dubai	2011-11-06
+290421	Zidm	Zidm	Zidm	25.48333	56.15	S	RUIN	AE		04				0		507	Asia/Dubai	2011-11-06
+290422	Zibara	Zibara	Zibara,Zibarah,ZibÄrah	24.61889	54.63417	T	DUNE	AE		01				0		11	Asia/Dubai	2011-11-06
+290423	Zi‘Äb	Zi`ab	Za`ab,Za‘Äb,Zi`ab,Zi‘Äb	25.03333	56.36667	L	TRB	AE		06				0		-9999	Asia/Dubai	2011-11-06
+290424	ZayqÄt	Zayqat	Zaiqat,Zayqat,ZayqÄt	23.36667	52.15	S	OILW	AE	AE	01				0		52	Asia/Dubai	2011-11-06
+290425	ZayqÄt	Zayqat	Zayqat,ZayqÄt	23.35	52.15	S	CMPQ	AE		01				0		53	Asia/Dubai	2011-11-06
+290426	MÄ«nÄ’ ZÄyid	Mina' Zayid	Mina Zayed,Mina' Zayid,MÄ«nÄ’ ZÄyid,Port Zayed,mynaʾ zayd,ميناء زايد	24.52518	54.38651	L	PRT	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290427	Ramlat Zayd	Ramlat Zayd	Ramlat Zaid,Ramlat Zayd	24.21667	55.2	T	DUNE	AE	AE	01				0		150	Asia/Dubai	2011-11-06
+290428	Bi’r Zayd	Bi'r Zayd	Bada` Zaid,Bada‘ Zaid,Bi'r Zayd,Bir Zaid,Bi’r Zayd	24.2	55.35	H	WLL	AE		01				0		168	Asia/Dubai	2011-11-06
+290429	Bid‘ Zayd	Bid` Zayd	Bada' Zaid,Bada’ Zaid,Bid` Zayd,Bid‘ Zayd	24.21667	55.11667	H	WLL	AE		01				0		118	Asia/Dubai	2011-11-06
+290430	Khawr Zawrah	Khawr Zawrah	Khawr Zawrah,Khawr Zora,Khawr az Zawra,Khawr az ZawrÄ	25.44417	55.47944	H	INLT	AE	AE	02				0		-9999	Asia/Dubai	2011-11-06
+290431	JazÄ«rat Zawrah	Jazirat Zawrah	Al-Zura,Al-ZÅ«rÄ,Jazirat Zawrah,JazÄ«rat Zawrah,Zora Island	25.43778	55.46472	T	ISL	AE	AE	00				0		8	Asia/Dubai	2011-11-06
+290432	Zawr	Zawr	Zawr	25.5275	55.59667	L	LCTY	AE		07				0		19	Asia/Dubai	2011-11-06
+290433	Z̧awÄhir	Zawahir	Dhawahir,DhawÄhir,Dhuwahir,Zawahir,Z̧awÄhir	24.33333	55.58333	L	TRB	AE	AE	01				0		208	Asia/Dubai	2011-11-06
+290434	ZÄrÅ«b	Zarub	Zarub,ZarÅ«b,ZÄrÅ«b	25.01806	56.21	V	CULT	AE	AE	06				0		406	Asia/Dubai	2011-11-06
+290435	ZarqÄ’	Zarqa'	Zarqa',ZarqÄ’	25.34622	55.87143	L	LCTY	AE		07				0		136	Asia/Dubai	2011-11-06
+290436	ZarÄrah	Zararah	Zararah,Zarrara,Zarrarah,Zarta,ZarÄrah	22.66667	54.13333	L	OILF	AE	AE	01				0		145	Asia/Dubai	2011-11-06
+290437	ZarÄrah	Zararah	Zararah,ZarÄrah	22.87043	53.83424	T	DPR	AE		01				0		51	Asia/Dubai	2011-11-06
+290438	ZarÄf	Zaraf	Zaraf,ZarÄf	23.79064	54.21261	H	WLL	AE		01				0		84	Asia/Dubai	2011-11-06
+290439	Qarn Zaqīq	Qarn Zaqiq	Qarn Bu Naidar,Qarn Zaqiq,Qarn Zaqīq,Qarn al Khabta	24.31463	52.59967	T	HLL	AE		01				0		129	Asia/Dubai	2011-11-06
+290440	Jabal az̧ Z̧annah	Jabal az Zannah	Az Zannah,Az̧ Z̧annah,Djebel Dhanna,Jabal Danna,Jabal Dhannah,Jabal Dhanni,Jabal az Zannah,Jabal az̧ Z̧annah	24.1709	52.59488	T	HLL	AE		01				0		111	Asia/Dubai	2011-11-06
+290441	Dawḩat az̧ Z̧annah	Dawhat az Zannah	Dawhat az Zannah,Dawḩat az̧ Z̧annah	24.15252	52.71794	H	BGHT	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290442	Z̧anḩah	Zanhah	Ghob,Zanhah,Z̧anḩah	25.5659	56.20217	P	PPL	AE		04				0		93	Asia/Dubai	2011-11-06
+290443	Ţawī Za‘lah	Tawi Za`lah	Tawi Za`lah,Ţawī Za‘lah	24.34848	55.43925	H	WLLQ	AE		01				0		178	Asia/Dubai	2011-11-06
+290444	Sayḩ Za‘lah	Sayh Za`lah	Sayh Za`lah,Sayḩ Za‘lah	24.33804	55.4268	T	TRGD	AE		01				0		179	Asia/Dubai	2011-11-06
+290445	Sayḩ Za‘lah	Sayh Za`lah	Sayh Za`lah,Sayḩ Za‘lah	24.2894	55.41804	T	TRGD	AE		01				0		175	Asia/Dubai	2011-11-06
+290446	Sayḩ Za‘lah	Sayh Za`lah	Sayh Za`lah,Sayḩ Za‘lah	24.28333	55.41667	T	TRGD	AE		01				0		163	Asia/Dubai	2011-11-06
+290447	ZÄkhir	Zakhir	Zakhir,ZÄkhir	24.11667	55.68333	S	HSE	AE		01				0		246	Asia/Dubai	2011-11-06
+290448	Ţawī ZĒid	Tawi Za'id	Tawi Za'id,Ţawī ZĒid	25.59556	55.88444	H	WLL	AE		07				0		35	Asia/Dubai	2011-11-06
+290449	Z̧ahūriyīn	Zahuriyin	Zahuriyin,Z̧ahūriyīn	26.05	56.13333	L	TRB	AE		05				0		680	Asia/Dubai	2011-11-06
+290450	Zaḩūm	Zahum	Zahum,Zaḩūm,Zihum	25.25	56.06667	L	TRB	AE	AE	00				0		285	Asia/Dubai	2011-11-06
+290451	ZahrÄnÄ«	Zahrani	Zahrani,ZahrÄnÄ«	23.21667	54.18333	H	WLL	AE		01				0		116	Asia/Dubai	2011-11-06
+290452	Bū Ţabr	Bu Tabr	Bu Tabr,Bū Ţabr,Dahar,Dhahar,Zahr,Z̧ahr	24.35944	52.60583	S	FRM	AE	AE	01				0		-9999	Asia/Dubai	2011-11-06
+290453	WÄdÄ« Z̧aḩah	Wadi Zahah	Wadi Zahah,WÄdÄ« Z̧aḩah	25.57036	56.20654	H	WAD	AE		04				0		76	Asia/Dubai	2011-11-06
+290454	Z̧afÄ«r	Zafir	Dafir,Dhafir,DhafÄ«r,Zafir,Z̧afÄ«r,á¸Äfir	23.12732	53.75439	P	PPL	AE		01				0		198	Asia/Dubai	2011-11-06
+290455	Z̧afīr	Zafir	Zafir,Z̧afīr	23.12027	53.75554	T	DPR	AE		01				0		82	Asia/Dubai	2011-11-06
+290456	Qarn Zabut	Qarn Zabut	Qarn Zabut	23.99048	54.07328	T	HLL	AE		01				0		20	Asia/Dubai	2011-11-06
+290457	Za‘bīl	Za`bil	Za`bil,Za‘bīl	25.22402	55.30452	S	PAL	AE		03				0		33	Asia/Dubai	2011-11-06
+290458	Å¢awÄ« Za‘ÄbÄ«yah	Tawi Za`abiyah	Tawi Za`abiyah,Å¢awÄ« Za‘ÄbÄ«yah	25.24917	55.88472	H	WLL	AE		06				0		128	Asia/Dubai	2011-11-06
+290459	Za‘Äb	Za`ab	Za`ab,Za‘Äb	25.68751	55.84732	L	TRB	AE		07				0		16	Asia/Dubai	2011-11-06
+290460	Ţawī Yudayyah	Tawi Yudayyah	Bir Yidayah,Tawi Yudayyah,Yidaiya,Ţawī Yudayyah	24.88904	55.78333	H	WLL	AE		06				0		203	Asia/Dubai	2011-11-06
+290461	Jabal YÄ«s	Jabal Yis	Jabal Yis,Jabal YÄ«s	25.35781	56.1109	T	MT	AE		04				0		683	Asia/Dubai	2011-11-06
+290462	Yinas	Yinas	Yinas	25.73158	56.13405	P	PPL	AE		05				0		1079	Asia/Dubai	2011-11-06
+290463	Yilak	Yilak	Yilak	23.06607	53.67436	T	DPR	AE		01				0		75	Asia/Dubai	2011-11-06
+290464	Yilaiyis	Yilaiyis	Yilaiyis	23.86184	55.43317	T	DUNE	AE		01				0		152	Asia/Dubai	2011-11-06
+290465	WÄdÄ« Yifan	Wadi Yifan	Wadi Yifan,WÄdÄ« Yifan	25.06066	56.30444	H	WAD	AE		04				0		38	Asia/Dubai	2011-11-06
+290466	Jabal Yibir	Jabal Yibir	Jabal Yibir	25.66752	56.13572	T	MT	AE		05				0	1527	1485	Asia/Dubai	2011-02-09
+290467	YÄsÄt ÅžaghÄ«rah	Yasat Saghirah	Yasat Saghirah,YÄsÄt ÅžaghÄ«rah	24.15912	52.0007	T	ISL	AE		01				0		6	Asia/Dubai	2011-11-06
+290468	Al YÄsÄt as Suflá	Al Yasat as Sufla	Al Yasat as Sufla,Al YÄsÄt as Suflá,Yasat Safli,YÄsÄt SaflÄ«	24.18675	51.9948	T	ISL	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290469	Al YÄsÄt al ‘UlyÄ	Al Yasat al `Ulya	Al Yasat al `Ulya,Al YÄsÄt al ‘UlyÄ,Yasat `Ali,YÄsÄt ‘AlÄ«	24.23662	52.01234	T	ISL	AE		01				0		10	Asia/Dubai	2011-11-06
+290470	Yarīrah	Yarirah	Yarirah,Yarīrah	22.8707	54.22656	T	DPR	AE		01				0		94	Asia/Dubai	2011-11-06
+290471	WÄdÄ« YamÄn	Wadi Yaman	Wadi Yaman,WÄdÄ« YamÄn	25.38499	56.32647	H	WAD	AE		06				0		53	Asia/Dubai	2011-11-06
+290472	Å¢awÄ« YÄl	Tawi Yal	Tawi Yal,Å¢awÄ« YÄl	25.42336	56.10511	H	WLL	AE		04				0		302	Asia/Dubai	2011-11-06
+290473	YÄkhÅ«n	Yakhun	Yakhun,YÄkhÅ«n	24.88795	55.72161	T	DUNE	AE		06				0		210	Asia/Dubai	2011-11-06
+290474	Ya‘rid	Ya`rid	Ya`rid,Yairad,Ya‘rid,Yerad	24.80324	55.03569	T	SAND	AE		01				0		28	Asia/Dubai	2011-11-06
+290475	WÄdÄ« Yaif	Wadi Yaif	Wadi Yaif,WÄdÄ« Yaif	24.93722	56.1025	H	WAD	AE		05				0		295	Asia/Dubai	2011-11-06
+290476	Yaif	Yaif	Yaif	24.94	56.09722	V	CULT	AE		05				0		530	Asia/Dubai	2011-11-06
+290477	Yahli	Yahli	Yahli	23.9879	54.70761	H	WLL	AE		01				0		106	Asia/Dubai	2011-11-06
+290478	Ţawī Yaḩfar	Tawi Yahfar	Tawi Yahfar,Ţawī Yaḩfar	25.02556	55.83361	H	WLL	AE		06				0		172	Asia/Dubai	2011-11-06
+290479	Sayḩ YÄfÅ«kh	Sayh Yafukh	Sayh Yafukh,Sayḩ YÄfÅ«kh	23.6458	55.49207	T	TRGD	AE		01				0		167	Asia/Dubai	2011-11-06
+290480	Yafnah	Yafnah	Yafnah,Yifnah	25.73424	56.09919	V	CULT	AE		05				0		766	Asia/Dubai	2011-11-06
+290481	Jazīrat Yabr	Jazirat Yabr	Jazirat Yabr,Jazīrat Yabr	24.31856	52.71939	T	ISL	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290482	Ţawī Yabbah	Tawi Yabbah	Tawi Yabbah,Ţawī Yabbah	25.35306	56.05111	H	WLL	AE		04				0		266	Asia/Dubai	2011-11-06
+290483	Ya‘alla	Ya`alla	Ya`alla,Ya‘alla	23.90646	54.99539	T	DUNE	AE		01				0		135	Asia/Dubai	2011-11-06
+290484	WÄdÄ« Ya’a	Wadi Ya'a	Wadi Ya'a,WÄdÄ« Ya’a	25.09611	56.26028	H	WAD	AE		04				0		224	Asia/Dubai	2011-11-06
+290485	Jabal Wutayd	Jabal Wutayd	Jabal Witeid,Jabal Wutaid,Jabal Wutayd	23.93615	52.29663	T	HLL	AE		01				0		40	Asia/Dubai	2011-11-06
+290486	Å¢awÄ« WushÄḩ	Tawi Wushah	Tawi Wishah,Tawi Wushah,TÄwÄ« Wishah,Wusha,Å¢awÄ« WushÄḩ	25.22834	55.91456	H	WLL	AE		06				0		143	Asia/Dubai	2011-11-06
+290487	WÄdÄ« Wurayyah	Wadi Wurayyah	Wadi Waraiya,Wadi Wurayyah,WÄdÄ« Waraiya,WÄdÄ« Wurayyah	25.38343	56.26224	H	WAD	AE		04				0		415	Asia/Dubai	2011-11-06
+290488	Wuqnah	Wuqnah	Wuqnah	23.0326	53.67397	T	DPR	AE		01				0		86	Asia/Dubai	2011-11-06
+290489	Wuḩaydah	Wuhaydah	Wuhaydah,Wuḩaydah	23.13333	53.93333	L	OAS	AE		01				0		98	Asia/Dubai	2011-11-06
+290490	Wuḩaydah	Wuhaydah	Wuhaida,Wuhaydah,Wuḩaydah	23.11764	53.77261	L	OAS	AE		01				0		194	Asia/Dubai	2011-11-06
+290491	WudibsÄ	Wudibsa	Wudibsa,WudibsÄ	23.73726	52.25189	T	SAND	AE		01				0		32	Asia/Dubai	2011-11-06
+290492	WÄdÄ« WiqÄ’	Wadi Wiqa'	Wadi Wiqa',Wadi al Amlah,WÄdÄ« WiqÄ’,WÄdÄ« al Amlaḩ	25.19143	56.04543	H	WAD	AE		05				0		210	Asia/Dubai	2011-11-06
+290493	Ţawī Widd	Tawi Widd	Tawi Wid,Tawi Widd,Ţawī Wid,Ţawī Widd	25.63296	56.01934	H	WLL	AE		05				0		108	Asia/Dubai	2011-11-06
+290494	Webb Rock	Webb Rock	Webb Rock	24.08437	52.2437	T	RK	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290495	WÄdÄ« Wayqah	Wadi Wayqah	Wadi Wayqah,WÄdÄ« Wayqah	25.32211	56.12861	H	WAD	AE		04				0		403	Asia/Dubai	2011-11-06
+290496	Watigh	Watigh	Watigh	23.68728	55.07948	T	DUNE	AE		01				0		139	Asia/Dubai	2011-11-06
+290497	Watauq	Watauq	Watauq	24.30306	54.91357	H	WLL	AE		01				0		70	Asia/Dubai	2011-11-06
+290498	Raml WÄsiÅ£	Raml Wasit	Raml Wasit,Raml WÄsiÅ£,Wasit,WÄsit	25.3425	55.47167	T	SAND	AE	AE	06				0		21	Asia/Dubai	2011-11-06
+290499	WÄsiÅ£	Wasit	Wasit,WÄsiÅ£	25.72194	55.87806	H	WLL	AE		05				0		32	Asia/Dubai	2011-11-06
+290500	WÄsiÅ£	Wasit	Wasit,WÄsiÅ£	25.60698	56.2548	P	PPL	AE		04				0		9	Asia/Dubai	2011-11-06
+290501	WÄsiÅ£	Wasit	Wasit,WÄsiÅ£	23.0036	53.44942	T	DPR	AE		01				0		176	Asia/Dubai	2011-11-06
+290502	Wasaţ	Wasat	Wasat,Wasaţ	22.80611	53.31093	H	WLL	AE		01				0		70	Asia/Dubai	2011-11-06
+290503	WarÄ«sÄn	Warisan	Warisan,WarÄ«sÄn	25.16744	55.40708	P	PPL	AE		03				0		20	Asia/Dubai	2011-11-06
+290504	Ţawī Waraqah	Tawi Waraqah	Tawi Waraqah,Ţawī Waraqah	24.77782	56.14991	H	WLL	AE		03				0		341	Asia/Dubai	2011-11-06
+290505	Khaţm Waraq	Khatm Waraq	Khatm Waraq,Khaţm Waraq	24.36667	55.45	T	DUNE	AE		01				0		158	Asia/Dubai	2011-11-06
+290506	WarÄq	Waraq	Waraq,WarÄq	22.97996	54.18115	T	DPR	AE		01				0		98	Asia/Dubai	2011-11-06
+290507	WÄdÄ« Wamm	Wadi Wamm	Wadi Wamm,WÄdÄ« Wamm	25.60512	56.22705	H	WAD	AE		04				0		42	Asia/Dubai	2011-11-06
+290508	Jabal Wamm	Jabal Wamm	Jabal Wamm	25.6021	56.19906	T	MT	AE		04				0		490	Asia/Dubai	2011-11-06
+290509	Wamm	Wamm	Wamm	25.60031	56.22838	P	PPL	AE		04				0		42	Asia/Dubai	2011-11-06
+290510	Walters Shoal	Walters Shoal	Walters Shoal	24.39524	52.47387	H	RF	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290511	Sayḩ al Wakrah	Sayh al Wakrah	Sayh al Wakrah,Sayḩ al Wakrah	24.59461	54.96476	T	TRGD	AE		01				0		57	Asia/Dubai	2011-11-06
+290512	Wahala	Wahala	Wahala,Wahlah,Waḩlah	24.90897	56.30316	P	PPL	AE		02				0		71	Asia/Muscat	2011-11-06
+290513	WÄdÄ« WahÄ«yah	Wadi Wahiyah	Wadi Wahiya,Wadi Wahiyah,WÄdÄ« Wahiya,WÄdÄ« WahÄ«yah	24.8183	56.15931	H	WAD	AE		02				0		282	Asia/Dubai	2011-11-06
+290514	Jabal Waḩīd	Jabal Wahid	Jabal Wahid,Jabal Waḩīd,The Hummock	24.31115	52.61141	T	HLL	AE		01				0		45	Asia/Dubai	2011-11-06
+290515	WÄḩid	Wahid	Wahid,WÄḩid	24.82444	56.08111	V	CULT	AE		02				0		339	Asia/Dubai	2011-11-06
+290516	WaharmÄ	Waharma	Waharma,WaharmÄ	22.75519	53.44766	T	DPR	AE		01				0		66	Asia/Dubai	2011-11-06
+290517	Wafd	Wafd	Qutuf,Quţūf,Waafit,Wafd,Wafid,Wefid	23.10262	53.71159	P	PPL	AE		01				0		84	Asia/Dubai	2011-11-06
+290518	Wad Wid	Wad Wid	Wad Wid	25.62515	56.01396	P	PPL	AE		05				0		17	Asia/Dubai	2011-11-06
+290519	WÄdÄ« ShÄ«	Wadi Shi	Wadi Shi,WÄdÄ« ShÄ«	25.35	56.31667	P	PPL	AE		06				0		77	Asia/Dubai	2011-11-06
+290520	Ḩabl WÄdÄ« ÅžafÄ	Habl Wadi Safa	Habl Wadi Safa,Wadi Safa,WÄdÄ« ÅžafÄ,Ḩabl WÄdÄ« ÅžafÄ	25.06092	55.27055	T	DUNE	AE		03				0		33	Asia/Dubai	2011-11-06
+290521	Wadhīl	Wadhil	Wadhil,Wadhīl,Wedheil,Wudhayl	23.0474	54.13332	P	PPL	AE		01				0		99	Asia/Dubai	2011-11-06
+290522	WÄdÄ« Wa‘bayn	Wadi Wa`bayn	Wadi Wa`bayn,WÄdÄ« Wa‘bayn	25.57261	56.12374	H	WAD	AE		04				0		400	Asia/Dubai	2011-11-06
+290523	Wa‘bayn	Wa`bayn	Wa'abain,Wa`bayn,Wa‘bayn,Wa’abain	25.57046	56.13536	P	PPL	AE		04				0		357	Asia/Dubai	2011-11-06
+290524	‘Uzlah	`Uzlah	`Uzalah,`Uzlah,‘Uzalah,‘Uzlah	22.99545	54.16649	T	DPR	AE		01				0		91	Asia/Dubai	2011-11-06
+290525	WÄdÄ« al ‘Uyaynah	Wadi al `Uyaynah	Wadi Ayeina,Wadi al `Uyaynah,WÄdÄ« Ayeina,WÄdÄ« al ‘Uyaynah	25.4742	56.18514	H	WAD	AE		04				0		176	Asia/Dubai	2011-11-06
+290526	GhaffÄt al ‘Uwayyirah	Ghaffat al `Uwayyirah	Ghaffat al `Uwayyirah,GhaffÄt al ‘Uwayyirah	24.46667	55.31667	T	DUNE	AE		01				0		152	Asia/Dubai	2011-11-06
+290527	Jabal al ‘Uwayyin	Jabal al `Uwayyin	Jabal al `Uwayyin,Jabal al ‘Uwayyin	25.36083	56.32395	T	MT	AE		06				0		583	Asia/Dubai	2011-11-06
+290528	Ţawī ‘Uwayyah	Tawi `Uwayyah	Tawi `Uwayyah,Ţawī ‘Uwayyah	25.58472	55.76028	H	WLL	AE		07				0		26	Asia/Dubai	2011-11-06
+290529	‘Uwayyah	`Uwayyah	`Uwayyah,‘Uwayyah	25.11278	55.30367	L	LCTY	AE		03				0		24	Asia/Dubai	2011-11-06
+290530	Qarn ‘Uwayşim	Qarn `Uwaysim	Qarn `Uwaysim,Qarn ‘Uwayşim	23.86667	53.43333	T	HLL	AE		01				0		70	Asia/Dubai	2011-11-06
+290531	‘Uwayşim	`Uwaysim	`Uwaisim,`Uwaysim,‘Uwaisim,‘Uwayşim	23.88333	53.38333	H	WLL	AE		01				0		66	Asia/Dubai	2011-11-06
+290532	Sabkhat ‘Uwayrah	Sabkhat `Uwayrah	Sabkhat `Uwayrah,Sabkhat ‘Uwayrah	23.95006	55.3068	H	SBKH	AE		01				0		131	Asia/Dubai	2011-11-06
+290533	NiqyÄn ‘Uwayrah	Niqyan `Uwayrah	Niqyan `Uwayrah,NiqyÄn ‘Uwayrah	23.96497	55.28962	T	DUNE	AE		01				0		181	Asia/Dubai	2011-11-06
+290534	Ţawī al ‘Uwaynīyah	Tawi al `Uwayniyah	Tawi al `Uwayniyah,Ţawī al ‘Uwaynīyah	25.31667	55.76667	H	WLL	AE		06				0		86	Asia/Dubai	2011-11-06
+290535	‘Uwayjir	`Uwayjir	`Uwayjir,‘Uwayjir	24.71667	55.16667	T	HLL	AE		03				0		87	Asia/Dubai	2011-11-06
+290536	‘Uwayj al ‘Abīd	`Uwayj al `Abid	`Uwayj al `Abid,‘Uwayj al ‘Abīd	24.11667	55.06667	T	DUNE	AE		01				0		119	Asia/Dubai	2011-11-06
+290537	‘Uwayj al ‘Abīd	`Uwayj al `Abid	`Uwayj al `Abid,‘Uwayj al ‘Abīd	24.13333	55.06667	T	DPR	AE		01				0		125	Asia/Dubai	2011-11-06
+290538	Jabal ‘Uwaybil	Jabal `Uwaybil	Jabal `Uwaybil,Jabal ‘Uwaybil	25.44021	55.96991	T	DUNE	AE		05				0		189	Asia/Dubai	2011-11-06
+290539	Jabal al ‘Uţayfah	Jabal al `Utayfah	Jabal al `Utayfah,Jabal al ‘Utayfah,Jabal al ‘Uţayfah	25.51024	56.02862	T	HLL	AE		04				0		278	Asia/Dubai	2011-11-06
+290540	‘Ushsh	`Ushsh	'Ishsh,Al Isha,Jazirat `Ish,Jazīrat ‘Ish,Ushsh,`Ashsh,`Ish,`Ushsh,‘Ashsh,‘Ish,‘Ushsh,’Ishsh	24.30488	52.87712	T	ISL	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290541	WÄdÄ« Ushayl	Wadi Ushayl	Wadi Ushail,Wadi Ushayl,WÄdÄ« Ushail,WÄdÄ« Ushayl	24.90515	56.08586	H	WAD	AE		05				0		287	Asia/Dubai	2011-11-06
+290542	WÄdÄ« ‘Usaylah	Wadi `Usaylah	Wadi `Usaylah,WÄdÄ« ‘Usaylah	25.69178	56.03764	H	WAD	AE		05				0		48	Asia/Dubai	2011-11-06
+290543	Sabkhat al ‘Urūq	Sabkhat al `Uruq	Sabkhat al `Uruq,Sabkhat al ‘Urūq	23.90811	54.18872	H	SBKH	AE		01				0		40	Asia/Dubai	2011-11-06
+290544	‘UrqÅ«b SibÄ’	`Urqub Siba'	Sbaa,Siba`,SibÄ‘,`Urqub Siba',‘UrqÅ«b SibÄ’	25.27824	55.47043	L	LCTY	AE		03				0		24	Asia/Dubai	2011-11-06
+290545	‘Urqūb Juwayzah	`Urqub Juwayzah	`Urqub Juwayzah,‘Urqūb Juwayzah	24.90586	55.4608	T	SCRP	AE		03				0		107	Asia/Dubai	2011-11-06
+290546	‘Urqūb Juwayza	`Urqub Juwayza	`Urqub Juwayza,‘Urqūb Juwayza	24.93333	55.46667	P	PPL	AE		03				0		102	Asia/Dubai	2011-11-06
+290547	‘Uraykah	`Uraykah	`Uraykah,‘Uraykah	24.36667	55.45	T	TRGD	AE		01				0		158	Asia/Dubai	2011-11-06
+290548	‘Uraykah	`Uraykah	'Ureika,`Uraykah,‘Uraykah,’Ureika	24.33333	55.46667	T	HLL	AE		01				0		199	Asia/Dubai	2011-11-06
+290549	WÄdÄ« ‘Urayf	Wadi `Urayf	Wadi `Urayf,WÄdÄ« ‘Urayf	25.49385	56.06209	H	WAD	AE		04				0		147	Asia/Dubai	2011-11-06
+290550	‘Uraybī	`Uraybi	Araibi,`Uraybi,‘Uraybī	25.78945	55.97665	P	PPLX	AE		05				0		20	Asia/Dubai	2011-11-06
+290551	‘Uqayyiq	`Uqayyiq	`Uqayyiq,‘Uqayyiq	24.53333	54.75	H	WLL	AE		01				0		33	Asia/Dubai	2011-11-06
+290552	‘Uqayyiq	`Uqayyiq	`Uqayyiq,‘Uqayyiq	24.52079	54.66317	T	DUNE	AE		01				0		7	Asia/Dubai	2011-11-06
+290553	Ţawī ‘Uqayr	Tawi `Uqayr	Tawi `Uqayr,Ţawī ‘Uqayr	23.78033	55.4708	H	WLL	AE		01				0		146	Asia/Dubai	2011-11-06
+290554	‘Uqayr	`Uqayr	`Uqayr,‘Uqayr	25.28302	56.36435	P	PPL	AE		06				0		23	Asia/Dubai	2011-11-06
+290555	‘UqaydÄt	`Uqaydat	Al `Uqaydat,Al ‘UqaydÄt,`Uqaydat,‘UqaydÄt	24.78556	55.78972	V	TREE	AE		06				0		275	Asia/Dubai	2011-11-06
+290556	Jabal ‘UqaybÄt	Jabal `Uqaybat	Jabal `Uqaybat,Jabal ‘UqaybÄt	25.1275	56.31278	T	HLL	AE		04				0		155	Asia/Dubai	2011-11-06
+290557	United Arab Emirates	United Arab Emirates	Ab'adnanya Arabskia Emiraty,Al Imarat al `Arabiyah al Muttahidah,Al ImÄrÄt al ‘ArabÄ«yah al Muttaḩidah,Aontas na nEimiriochtai Arabacha,Aontas na nÉimíríochtaí Arabacha,Apvienotie Arabu Emirati,Apvienotie ArÄbu EmirÄti,Araabia UEhendemiraadid,Araabia Ãœhendemiraadid,Arab Federation of Gulf States,Arab Gulf Federation,Arabiar Emirerri Batuak,Arabiar Emirrerri Batuak,Arabiemiirikunnat,Birlashgan Arab Amirliglar,Birlesik Arap Emirlikleri,BirleÅŸik Arap Emirlikleri,Cac Tieu Vuong quoc A-rap Thong nhat,Cac Tieu vuong quoc A rap Thong nhat,Các Tiểu VÆ°Æ¡ng quốc A-rập Thống nhất,Các Tiểu vÆ°Æ¡ng quốc Ả rập Thống nhất,Dawlat Ittihad al Imarat al `Arabiyah,Dawlat IttiḩÄd al ImÄrÄt al ‘ArabÄ«yah,De forente arabiske emirater,Dei sameinte arabiske emirata,Egyesuelt Arab Emiratus,Egyesuelt Arab Emirsegek,Egyesült Arab Emirátus,Egyesült Arab Emírségek,Emira Arab Ini,Emirados Arabes Unidos,Emirados Ãrabes Unidos,Emiraethau Arabaidd Unedig,Emiratele Arabe Unite,Emiratet Arabe te Bashkuara,Emiratet e Bashkuara Arabe,Emirati Arabi Uniti,Emirati Gharab Maqghuda,Emirati Għarab Maqgħuda,Emiratos Arabe Unite,Emiratos Arabes Unidos,Emiratos Arabes Unitos,Emiratos Ãrabes Unidos,Emiratos Ãrabes Unidos - الإمارات العربيّة المتّحدة,Emirats Arabes Unis,Emirats Arabis Units,Emirats Arabs Units,Emirats arabes units,Emirats arabos unis,Emirats Àrabs Units,Emiratus Arabi Uniti,Emirelezhiou Arab Unanet,Emirelezhioù Arab Unanet,Emiriah Arab Bersatu,Enomena Arabika Emirata,Falme za Kiarabu,Federation of Arab Emirates,Federation of Arabian Emirates,Federation of Arabian Gulf Emirates,Feriene Arabyske Emiraten,Foerenade Arabemiraten,Forenede Arabiske Emirater,Förenade Arabemiraten,Imaaraadka Carabta ee Midoobay,Jungtiniai Arabu Emyratai,Jungtiniai Arabų Emyratai,Lemiraens Pebaloel Larabaenik,Lemiräns Pebalöl Larabänik,Mirnisinen Erebi yen Yekbuyi,Muugano wa Falme za Nchi za Kiarabu,Mîrnişînên Erebî yên Yekbûyî,OAEH,Ob"edinjonnye Arabskie Ehmiraty,Obedineni Arabski Emirstva,Obedineti Arapski Emirati,Obuedinennye Arabskie Ehmiraty,Ovttastuvvan Arabaemirahtat,Ovttastuvvan Arábaemiráhtat,Pennternasedh Unys Arabek,Sameindu Emirrikini,Sameindu Emirríkini,Sameinudu arabisku furstadaemin,Sameinuðu arabísku furstadæmin,Spojene arabske emiraty,Spojené arabské emiráty,Trucial States,UAE,Ujedineni Arapski Emirati,Ujedinjeni Arapski Emirati,Uni Emirat Arab,Unio dels Emirats Arabs,Union of Arab Emirates,Unionita Araba Emirati,United Arab Emirates,Unió dels Emirats Àrabs,Unuigintaj Arabaj Emirlandoj,Unuigintaj Arabaj Emirlandos,UnuiÄintaj Arabaj Emirlandoj,UnuiÄintaj Arabaj Emirlandos,Vereenegt Arabesch Emirater,Vereenigte Araabsche Emiraten,Vereinegde Arabische Emirate,Vereinigte Arabische Emirate,Verenigde Arabiese Emirate,Verenigde Arabische Emiraten,Zdruzeni arabski emirati,Združeni arabski emirati,Zjednocene Arabske Emiraty,Zjednoczone Emiraty Arabskie,Zjednoćene Arabske Emiraty,a la bo lian he qiu zhang guo,aikkiya arapu amirakam,aikkiya arapu kuttatci,alab-emiliteu,arabetis gaertianebuli saamiroebi,arabu shou zhang guo lian bang,sanyukta arab rastram,sanyukta araba amirata,shrath xahrab xe mi rets,Èmirats arabes units,Èmirats arabos unis,Émirats Arabes Unis,Ηνωμένα ΑÏαβικά ΕμιÏάτα,Ðб'ÑÐ´Ð½Ð°Ð½Ñ‹Ñ ÐрабÑÐºÑ–Ñ Ð­Ð¼Ñ–Ñ€Ð°Ñ‚Ñ‹,Имороти Муттаҳидаи Ðраб,ОÐЭ,Об'єднані ÐрабÑькі Емірати,Обʼєднані ÐрабÑькі Емірати,Обединени ÐрабÑки ЕмирÑтва,Обединети ÐрапÑки Емирати,Объединенные ÐрабÑкие Эмираты,Объединённые ÐрабÑкие Эмираты,Уједињени ÐрапÑки Емирати,Õ„Õ«Õ¡ÖÕµÕ¡Õ¬ Ô±Ö€Õ¡Õ¢Õ¡Õ¯Õ¡Õ¶ Ô·Õ´Õ«Ö€Õ¡Õ©Õ¶Õ¥Ö€,×יחוד ×”×מירויות הערביות,×יחוד נסיכויות ערב,ברית ×”×מירויות הערביות,ئەرەب بىرلەشمە خەلىپىلىكى,الإمارات العربية المتحدة,الامارات العربية المتحدة,امارات متحده عربی,امارات متحدهٔ عربی,عمارات متحده ÛŒ عربی,متحده عرب امارات,Ù…ØªØ­Ø¯Û Ø¹Ø±Ø¨ امارات,ÜÜ¡ÜÜªÜ˜Ü¬Ü Ü¥ÜªÜ’ÜÜ¬Ü ÜšÜ•ÜܬÜ,संयà¥à¤•à¥à¤¤ अरब अमीरात,সংযà§à¦•à§à¦¤ আরব আমিরাত,à®à®•à¯à®•à®¿à®¯ அரப௠அமீரகமà¯,à®à®•à¯à®•à®¿à®¯ அரப௠கூடà¯à®Ÿà®¾à®Ÿà¯à®šà®¿,à´à´•àµà´¯ അറബൠഎമിരേറàµà´±àµà´•à´³àµâ€â€Œ,സംയàµà´•àµà´¤ അറബൠരാഷàµà´Ÿàµà´°à´‚,สหรัà¸à¸­à¸²à¸«à¸£à¸±à¸šà¹€à¸­à¸¡à¸´à¹€à¸£à¸•à¸ªà¹Œ,ສະຫະລັດອາຫລັບເອມິເລດ,ཡུ་ནའི་ཊེཊ་ཨ་ར བ་ཨེ་མི་རེཊསི,ཨ་རབ༠ཨི་མི་རཊ྄༠ཆིག་སྒྲིལ་རྒྱལ་à½à½–à¼,áƒáƒ áƒáƒ‘ეთის გáƒáƒ”რთიáƒáƒœáƒ”ბული ემირáƒáƒ¢áƒ”ბი,áƒáƒ áƒáƒ‘ეთის გáƒáƒ”რთიáƒáƒœáƒ”ბული სáƒáƒáƒ›áƒ˜áƒ áƒáƒ”ბი,የተባበሩት አረብ ኤáˆáˆ¬á‰µáˆµ,អáŸáž˜áž¸ážšáŸ‰áŸ‚ទអារ៉ាប់រួម,アラブ首長国連邦,阿拉伯è”åˆé…‹é•¿å›½,ì•„ëžì—미리트	24	54	A	PCLI	AE		00				4975593		12	Asia/Dubai	2011-11-06
+290558	Umm Åžayd	Umm Sayd	Umm Sayd,Umm Åžayd	22.94932	53.78481	T	DPR	AE		01				0		44	Asia/Dubai	2011-11-06
+290559	Umm Qays	Umm Qays	Umm Qays,Umm Qayz,Umm Qayz̧,Umm Qaz,Umm Qaz̧	22.92996	53.41542	H	WLL	AE		01				0		65	Asia/Dubai	2011-11-06
+290560	Umm Qays	Umm Qays	Umm Qays,Umm Qayz,Umm Qayz̧	22.92593	53.4138	T	DPR	AE		01				0		65	Asia/Dubai	2011-11-06
+290561	Umm JaÅŸÅŸÄr	Umm Jassar	Umm Jassar,Umm JaÅŸÅŸÄr,Umm Qasar,Umm Qassar,Umm QaÅŸÄr,Umm QaÅŸÅŸÄr,`Umm Gassar,‘Umm GaṣṣÄr	24.3914	52.77794	T	ISL	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290562	Umm Minhad	Umm Minhad	Umm Minhad	24.99359	55.3636	T	SAND	AE		03				0		40	Asia/Dubai	2011-11-06
+290564	Fasht Umm Jannah	Fasht Umm Jannah	Fasht Umm Janna,Fasht Umm Jannah,Janna	24.56959	51.5546	H	RF	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290565	Qarn Umm Ḩaşá	Qarn Umm Hasa	Qarn Umm Hasa,Qarn Umm Ḩaşá	25.11385	55.38284	T	DUNE	AE		03				0		49	Asia/Dubai	2011-11-06
+290566	Umm ḨafÄt	Umm Hafat	Umm Hafaf,Umm Hafat,Umm ḨafÄf,Umm ḨafÄt	23.84889	53.67889	H	WLL	AE	AE	01				0		76	Asia/Dubai	2011-11-06
+290567	Umm Khafat	Umm Khafat	Umm Hafaf,Umm Hafat,Umm Kafat,Umm Khafat,Umm ḨafÄf,Umm ḨafÄt	23.85336	53.69666	T	HLL	AE		01				0	95	89	Asia/Dubai	2011-11-06
+290568	Umm ḨÄbil	Umm Habil	Umm Habil,Umm ḨÄbil	22.99242	54.08237	T	DPR	AE		01				0		213	Asia/Dubai	2011-11-06
+290569	Ţawī Umm Ghuwayr	Tawi Umm Ghuwayr	Tawi Umm Ghuwayr,Ţawī Umm Ghuwayr	24.25341	55.0425	H	WLL	AE		01				0		125	Asia/Dubai	2011-11-06
+290570	Umm Ghaythah	Umm Ghaythah	Umm Gaita,Umm Ghaythah	24.10556	55.67583	T	DPR	AE	AE	01				0		244	Asia/Dubai	2011-11-06
+290571	JazÄ«rat Umm YafÄ«nah	Jazirat Umm Yafinah	Jazirat Umm Yafinah,JazÄ«rat Umm YafÄ«nah,Umm Fiyin,Umm FÄ«yÄ«n,jzyrt am yfynt,جزيرة أم ÙŠÙينة	24.48752	54.45009	T	ISL	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290572	Umm Dhuwaylah	Umm Dhuwaylah	Umm Dhuwaylah	24.45801	54.7294	H	WLL	AE		01				0		26	Asia/Dubai	2011-11-06
+290573	Umm Dhuwaylah	Umm Dhuwaylah	Umm Dhuwaylah	24.4692	54.723	T	SAND	AE		01				0		36	Asia/Dubai	2011-11-06
+290574	Umm Dasīs	Umm Dasis	Umm Dasis,Umm Dasīs,Umm Daysis,Umm Daysīs	23.81981	53.53876	L	GVL	AE		01				0		109	Asia/Dubai	2011-11-06
+290575	WÄdÄ« Umm ad Daqqayn	Wadi Umm ad Daqqayn	Wadi Umm Daqqayn,Wadi Umm ad Daqqayn,WÄdÄ« Umm Daqqayn,WÄdÄ« Umm ad Daqqayn	24.80556	56.20722	H	WAD	AE	AE	00				0		271	Asia/Dubai	2011-11-06
+290576	Kharaj Umm BiyÄt	Kharaj Umm Biyat	Kharaj Umm Bayat,Kharaj Umm BayÄt,Kharaj Umm Biyat,Kharaj Umm BiyÄt	25.15	55.4	H	WLL	AE	AE	03				0		7	Asia/Dubai	2011-11-06
+290577	Ţawī Umm Baraz	Tawi Umm Baraz	Tawi Umm Baraz,Ţawī Umm Baraz	22.94415	54.96468	H	WLL	AE		01				0		137	Asia/Dubai	2011-11-06
+290578	Sabkhat Umm Baraz	Sabkhat Umm Baraz	Sabkhat Umm Baraz	22.93458	55.03856	H	SBKH	AE		01				0		99	Asia/Dubai	2011-11-06
+290579	Umm Baraz	Umm Baraz	Umm Baraz	23.05	54.95	H	WLL	AE		01				0		125	Asia/Dubai	2011-11-06
+290580	Umm az Zumūl	Umm az Zumul	Umm Zamul,Umm Zamūl,Umm al Zamul,Umm az Zumul,Umm az Zumūl,Umm az-Zamul	22.70559	55.21205	H	WLL	AE		01				0		121	Asia/Dubai	2011-11-06
+290581	Umm Suqaym	Umm Suqaym	Umm Suqaym,Umm as Suqaym	25.15015	55.20587	P	PPLX	AE		03				0		26	Asia/Dubai	2011-11-06
+290582	Ḩaql Umm ash Shayf	Haql Umm ash Shayf	Haql Umm ash Shayf,Umm Shaif,Umm al-Shayf,Umm al-Sheif,Umm ash Sha'if,Umm ash ShÄ’if,Ḩaql Umm ash Shayf	25.2	53.2	L	OILF	AE	AE	01				0		-9999	Asia/Dubai	2011-11-06
+290583	Umm ar Raml	Umm ar Raml	Umm ar Raml	25.19658	55.41034	L	LCTY	AE		03				0		22	Asia/Dubai	2011-11-06
+290584	Umm ar Raml	Umm ar Raml	Umm ar Raml	25.23333	55.38333	T	DUNE	AE		03				0		29	Asia/Dubai	2011-11-06
+290585	WÄdÄ« Umm an NughÅ«l	Wadi Umm an Nughul	Wadi Umm an Nughul,WÄdÄ« Umm an NughÅ«l	25.34985	55.84553	H	WAD	AE		07				0		111	Asia/Dubai	2011-11-06
+290586	Ţawī Umm an Nughūl	Tawi Umm an Nughul	Tawi Umm an Nughul,Ţawī Umm an Nughūl	25.36333	55.87019	H	WLL	AE		07				0		92	Asia/Dubai	2011-11-06
+290587	Umm an NÄr	Umm an Nar	Jazirat Umm an Nar,JazÄ«rat Umm an NÄr,Umm an Nar,Umm an NÄr,`Umm al-Nar,am alnar,أم النار,‘Umm al-NÄr	24.44248	54.50948	T	ISL	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290588	Umm ‘Amīm	Umm `Amim	Jazirat Umm `min,Jazīrat Umm ‘mīn,Umm `Amim,Umm ‘Amīm	24.24128	53.39448	T	ISL	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290589	Umm al Qurayn	Umm al Qurayn	Umm Grain,Umm al Qurayn,`Umm Qrein,‘Umm Qrein	23.1	53.71667	P	PPL	AE	AE	01				0		181	Asia/Dubai	2011-11-06
+290590	Umm al Qurayn	Umm al Qurayn	Umm al Qurayn	23.09087	53.72477	L	OAS	AE		01				0		101	Asia/Dubai	2011-11-06
+290591	Umm al Qiţa‘	Umm al Qita`	Umm al Qita`,Umm al Qiţa‘	23.05522	53.53183	L	OAS	AE		01				0		127	Asia/Dubai	2011-11-06
+290592	Umm al Qird	Umm al Qird	Umm al Fa'iyah,Umm al FÄ’iyah,Umm al Qird	24.20527	54.79192	T	SAND	AE		01				0		66	Asia/Dubai	2011-11-06
+290593	Khawr Umm al Qaywayn	Khawr Umm al Qaywayn	Khawr Umm al Qaywayn	25.56	55.57972	H	BAY	AE		07				0		-9999	Asia/Dubai	2011-11-06
+290594	Umm al Qaywayn	Umm al Qaywayn	Um al Quweim,Umm al Qaiwain,Umm al Qawain,Umm al Qaywayn,Yumul al Quwain,am alqywyn,أم القيوين	25.56473	55.55517	P	PPLA	AE		07				44411		8	Asia/Dubai	2011-11-06
+290595	Umm al Qaywayn	Umm al Qaywayn	Oumm al Qaiwain,Oumm al Qaïwaïn,Skeikhdom of Umm al Qaiwain,Umm Al Quwain,Umm al Qawain,Umm al Qaywayn,Umm al Qiwain,am alqywyn,أم القيوين	25.5	55.75	A	ADM1	AE		07				56253		65	Asia/Dubai	2011-11-05
+290596	Kharīmat Umm al Muwayghir	Kharimat Umm al Muwayghir	Kharimat Umm al Muwayghir,Kharīmat Umm al Muwayghir	24.10497	54.80762	T	DPR	AE		01				0		74	Asia/Dubai	2011-11-06
+290597	Umm al Kurkum	Umm al Kurkum	Umm Kirkum,Umm Kurkum,Umm al Kurkum	24.39273	52.76497	T	ISL	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290598	Umm al Ḩişn	Umm al Hisn	Umm al Hisn,Umm al Ḩişn	23.01691	53.41646	S	FT	AE		01				0		118	Asia/Dubai	2011-11-06
+290599	Umm al Ḩişn	Umm al Hisn	Umm al Hisn,Umm al Ḩişn	23.01994	53.44238	T	DPR	AE		01				0		89	Asia/Dubai	2011-11-06
+290600	Umm al HiryÄn	Umm al Hiryan	Umm al Hiryan,Umm al HiryÄn	24.31722	55.79722	H	WLL	AE		01				0		280	Asia/Dubai	2011-11-06
+290601	Umm al Ḩaţab	Umm al Hatab	Jazirat Umm al Hatab,Jazīrat Umm al Ḩaţab,Umm al Halab Island,Umm al Hatab,Umm al Ḩaţab,Umm el Halab	24.21623	51.86389	T	ISL	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290602	Umm al Ghurūl	Umm al Ghurul	Umm al Ghurul,Umm al Ghurūl	23.84161	53.21056	L	GVL	AE		01				0		97	Asia/Dubai	2011-11-06
+290603	Umm al GhirbÄn	Umm al Ghirban	Umm al Gharban,Umm al GharbÄn,Umm al Ghirban,Umm al GhirbÄn	23.03841	53.55597	T	DPR	AE		01				0		71	Asia/Dubai	2011-11-06
+290604	WÄdÄ« Umm al GhÄt	Wadi Umm al Ghat	Wadi Umm al Ghat,WÄdÄ« Umm al GhÄt	24.87975	56.2778	H	WAD	AE		05				0		89	Asia/Dubai	2011-11-06
+290605	Jabal Umm al FurfÄr	Jabal Umm al Furfar	Jabal Umm al Farfar,Jabal Umm al FarfÄr,Jabal Umm al Furfar,Jabal Umm al FurfÄr	25.12448	56.22754	T	MT	AE		04				0		735	Asia/Dubai	2011-11-06
+290606	Umm al Birak	Umm al Birak	Umm al Barak,Umm al BarÄk,Umm al Birak,Umm al-Berak	24.56699	54.58394	T	ISL	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290607	Umm al BanÄdÄ«q	Umm al Banadiq	Umm al Banadig,Umm al Banadiq,Umm al BanÄdÄ«q	24.08705	55.27527	H	WLL	AE		01				0		151	Asia/Dubai	2011-11-06
+290608	Umm al AshÅ£Än	Umm al Ashtan	Umm al Ashtan,Umm al AshÅ£Än	23.58333	52.48333	H	WLL	AE		01				0		75	Asia/Dubai	2011-11-06
+290609	Umm al AshÅ£Än	Umm al Ashtan	Umm al Ashtan,Umm al AshÅ£Än,Umm al Lishtan,Umm al LishtÄn	23.76667	52.66667	T	SAND	AE	AE	01				0		79	Asia/Dubai	2011-11-06
+290610	Umm al AshÅ£Än	Umm al Ashtan	Umm al Ashtan,Umm al AshÅ£Än,Umm al Ishtan,Umm al IshÅ£Än	23.65248	52.45047	S	CMPQ	AE		01				0		64	Asia/Dubai	2011-11-06
+290611	Umm ‘Alaqah	Umm `Alaqah	Um `Alaqa,Um ‘Alaqa,Umm `Alaqah,Umm ‘Alaqah	24.0024	53.39048	T	HLL	AE		01				0		23	Asia/Dubai	2011-11-06
+290612	Ruqq Umm al ‘Anbar	Ruqq Umm al `Anbar	Ruqq Um el Umber,Ruqq Umm al `Anbar,Ruqq Umm al ‘Anbar,Umbar	24.60999	51.8836	H	SHOL	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290613	Sabkhat Umm al ‘Alqah	Sabkhat Umm al `Alqah	Sabkhat Umm al Alqa,Sabkhat Umm al `Alqah,Sabkhat Umm al ‘Alqah	23.63234	54.85535	H	SBKH	AE		01				0		115	Asia/Dubai	2011-11-06
+290614	Umm al ‘Alqah	Umm al `Alqah	Umm al Alqa,Umm al `Alqah,Umm al ‘Alqah	23.68333	54.83333	H	WLL	AE		01				0		105	Asia/Dubai	2011-11-06
+290615	Umm al Abyaḑ	Umm al Abyad	Umm al Abyad,Umm al Abyaḑ	25.09157	55.2481	H	WLLS	AE		03				0		26	Asia/Dubai	2011-11-06
+290616	Umm ad Dalkh	Umm ad Dalkh	Umm Addalkh,Umm ad Dalkh,Umm al Dalkh	24.53655	54.14598	L	OILF	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290617	Ghuyūţ ‘Ulayyah	Ghuyut `Ulayyah	Ghuyut `Ulayyah,Ghuyūţ ‘Ulayyah	23.85	54.73333	T	DPR	AE		01				0		96	Asia/Dubai	2011-11-06
+290618	‘Ūd Umm KhÄlid	`Ud Umm Khalid	`Ud Umm Khaldi,`Ud Umm Khalid,‘Ūd Umm KhaldÄ«,‘Ūd Umm KhÄlid	25.1375	55.39861	V	TREE	AE		03				0		35	Asia/Dubai	2011-11-06
+290619	Ra’s al ‘Udayd	Ra's al `Udayd	Al Odaid,Al `Udayd,Al ‘Udayd,Ra's al `Udayd,Ra’s al ‘Udayd	24.61667	51.43333	T	PT	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290620	Khawr al ‘Udayd	Khawr al `Udayd	Khawr al Wutayd,Khawr al Wuţayd,Khawr al `Udayd,Khawr al `Uwayd,Khawr al ‘Udayd,Khawr al ‘Uwayd,Khor al Odaid,Khor al Odeid,Khor al Ubeid,Khor al Wutaid,Khor al `Udaid,Khor al `Udeid,Khor al ‘Udaid,Khor al ‘Udeid	24.6	51.4	H	INLT	AE	AE	06				0		-9999	Asia/Dubai	2011-11-06
+290622	‘Ūd al Maţīnah	`Ud al Matinah	Aud al Matina,Awad al Matinah,Matina,Matinah,Matīna,Maţīnah,`Ud al Matinah,‘Ūd al Maţīnah	25.25583	55.44611	H	WLLS	AE		03				0		24	Asia/Dubai	2011-11-06
+290623	‘Ūd al Maţīnah	`Ud al Matinah	`Ud al Matinah,‘Ūd al Maţīnah	25.23815	55.4741	L	LCTY	AE		03				0		39	Asia/Dubai	2011-11-06
+290624	‘Ūd al BayḑÄ’	`Ud al Bayda'	Ud al Beida,`Ud al Bayda',‘Ūd al BayḑÄ’	25.01625	55.45533	P	PPL	AE		03				0		95	Asia/Dubai	2011-11-06
+290625	‘Ūd al Atham	`Ud al Atham	`Ud al Atham,‘Ūd al Atham	25.15	55.71667	V	TREE	AE		06				0		124	Asia/Dubai	2011-11-06
+290626	‘Ubaydil	`Ubaydil	`Ibeidil,`Ubaydhil,`Ubaydil,‘Ibeidil,‘Ubaydhil,‘Ubaydil	24.51667	51.33333	H	WLL	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290627	WÄdÄ« Å¢uwayyah	Wadi Tuwayyah	Wadi Tuwayyah,WÄdÄ« Å¢uwayyah	24.25722	55.68778	H	WAD	AE		01				0		267	Asia/Dubai	2011-11-06
+290628	Sayḩ Ţuwayyah	Sayh Tuwayyah	Sayh Tuwayyah,Sayḩ Ţuwayyah	24.39139	55.8275	T	PLN	AE		00				0		327	Asia/Dubai	2011-11-06
+290629	Sayḩ Tuwaysah	Sayh Tuwaysah	Sayh Tuways,Sayh Tuwaysah,Sayḩ Tuways,Sayḩ Tuwaysah	24.29278	55.505	T	DPR	AE	AE	01				0		195	Asia/Dubai	2011-11-06
+290630	Ţawī Ţuwayli‘	Tawi Tuwayli`	Tawi Tawaila,Tawi Tuwayli`,Tawi Tuwayyilah,Ţawī Tawaila,Ţawī Ţuwayli‘,Ţawī Ţuwayyilah	24.97679	55.7508	H	WLL	AE		06				0		171	Asia/Dubai	2011-11-06
+290631	Kharīmat Ţuwaylah	Kharimat Tuwaylah	Kharimat Tawaila,Kharimat Tuwaylah,Kharmat Tuwaylah,Kharmat Ţuwaylah,Kharīmat Ţuwaylah	24.1361	54.82632	T	TRGD	AE		01				0		92	Asia/Dubai	2011-11-06
+290632	Tuwayhil	Tuwayhil	Tuwayhil	23.4594	53.29148	H	WLL	AE		01				0		160	Asia/Dubai	2011-11-06
+290633	Jabal Tu‘ūs	Jabal Tu`us	Jabal Tu`us,Jabal Tus,Jabal Tu‘ūs	25.29958	56.11017	T	HLL	AE		04				0		550	Asia/Dubai	2011-11-06
+290634	Ţurayf	Turayf	Turayf,Ţurayf	23.0742	53.80161	T	DPR	AE		01				0		70	Asia/Dubai	2011-11-06
+290635	Ţunayq	Tunayq	Tanaij,Tanaiq,Tunaij,Tunayq,Ţunayq	25.86476	56.04169	L	TRB	AE		05				0		435	Asia/Dubai	2011-11-06
+290636	Tunayq	Tunayq	Tanaij,Tanaiq,Tunaij,Tunayq	25.26139	55.94944	L	TRB	AE		06				0		156	Asia/Dubai	2011-11-06
+290637	‘Aqabat Tūmaytayn	`Aqabat Tumaytayn	`Aqabat Tumaytayn,‘Aqabat Tūmaytayn	25.47656	56.35033	T	PASS	AE		04				0		17	Asia/Dubai	2011-11-06
+290638	Ţawī Ţubūl	Tawi Tubul	Tawi Tubul,Ţawī Ţubūl	24.22687	55.03957	H	WLL	AE		01				0		133	Asia/Dubai	2011-11-06
+290639	Jabal Ţubayqah	Jabal Tubayqah	Jabal Tubayqah,Jabal Ţubayqah	24.07825	56.00668	T	HLL	AE		01				0		429	Asia/Dubai	2011-11-06
+290640	Trucial Coast	Trucial Coast	Al Sahil,Al SÄḩil,Arab Coast,Pirate Coast,Sahil `Oman,Sahil `Uman,Sahil as Sulh al Bahri,Shamal,ShamÄl,SÄhil ‘OmÄn,SÄhil ‘UmÄn,SÄḩil aÅŸ Åžulḩ al BaḩrÄ«,Trucial Coast,Trucial Oman,Trucial `Uman,Trucial ‘Uman	24	53	L	RGN	AE	AE	00				0		37	Asia/Dubai	2011-11-06
+290641	Tina	Tina	Tina	23.81243	55.37423	T	DUNE	AE		01				0		182	Asia/Dubai	2011-11-06
+290642	Sabkhat Thuwaymah	Sabkhat Thuwaymah	Sabkhat Thuwaymah	24.0275	55.66806	L	SALT	AE		01				0		227	Asia/Dubai	2011-11-06
+290643	‘UrqÅ«b ThurayyÄ	`Urqub Thurayya	`Urqub Thurayya,‘UrqÅ«b ThurayyÄ	24.9	55.46667	T	DUNE	AE		03				0		139	Asia/Dubai	2011-11-06
+290644	Ţawī ath Thuqbah	Tawi ath Thuqbah	Tawi Thuqbah,Tawi ath Thuqbah,Ţawī Thuqbah,Ţawī ath Thuqbah	25.34611	55.84722	H	WLL	AE	AE	07				0		111	Asia/Dubai	2011-11-06
+290645	Ţawī Thuqaybah	Tawi Thuqaybah	Tawi Thuqaybah,Ţawī Thuqaybah	24.94829	55.81388	H	WLL	AE		06				0		190	Asia/Dubai	2011-11-06
+290646	Ţawī Thuqaybah	Tawi Thuqaybah	Tawi Thuqaybah,Ţawī Thuqaybah	23.55	55.28333	H	WLL	AE		01				0		181	Asia/Dubai	2011-11-06
+290647	Sabkhat Thuqaybah	Sabkhat Thuqaybah	Sabkhat Thuqaybah	23.58997	55.19693	H	SBKH	AE		01				0		114	Asia/Dubai	2011-11-06
+290648	Khawr Thumayrīyah	Khawr Thumayriyah	Khawr Thumayriyah,Khawr Thumayrīyah,Themairiyyah	24.15274	53.0014	H	CHNM	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290649	Thumayrīyah	Thumayriyah	Themairiyya,Themeiriyyah,Thimairiyah,Thumayriyah,Thumayrīyah	24.15033	53.0169	T	ISL	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290650	Thubaybah	Thubaybah	Thubaybah	23.68333	54.61667	H	WLL	AE		01				0		117	Asia/Dubai	2011-11-06
+290651	WÄdÄ« Thayb	Wadi Thayb	Wadi Thayb,Wadi Theeb,WÄdÄ« Thayb	25.24914	56.35124	H	WAD	AE		04				0		96	Asia/Dubai	2011-11-06
+290652	Jabal Thayb	Jabal Thayb	Jabal Thaib,Jabal Thayb	25.25854	56.31202	T	MT	AE		04				0		386	Asia/Dubai	2011-11-06
+290653	Thawrīyah	Thawriyah	Thawriyah,Thawrīyah	23.02531	53.9109	T	DPR	AE		01				0		68	Asia/Dubai	2011-11-06
+290654	Thawrīyah	Thawriyah	Thawriyah,Thawrīyah	22.99797	53.76585	T	DPR	AE		01				0		60	Asia/Dubai	2011-11-06
+290655	Khabb ath Thawr	Khabb ath Thawr	Khabb ath Thawr	24.2597	54.64343	T	SAND	AE		01				0		17	Asia/Dubai	2011-11-06
+290656	WÄdÄ« ThawbÄn	Wadi Thawban	Wadi Thauban,Wadi Thawban,WÄdÄ« Thauban,WÄdÄ« ThawbÄn	25.28582	56.04058	H	WAD	AE		04				0		225	Asia/Dubai	2011-11-06
+290657	Jabal ThawbÄn	Jabal Thawban	Jabal Thawban,Jabal ThawbÄn	25.32944	56.10306	T	MT	AE		04				0		726	Asia/Dubai	2011-11-06
+290658	TharwÄnÄ«yah	Tharwaniyah	Tharwaniyah,Tharwaniyya,Tharwaniyyah,TharwÄniyya,TharwÄniyyah,TharwÄnÄ«yah	23.11088	54.01572	P	PPL	AE		01				0		191	Asia/Dubai	2011-11-06
+290659	Thara’awn	Thara'awn	Thara'awn,Thara’awn	22.91004	54.32293	T	DPR	AE		01				0		162	Asia/Dubai	2011-11-06
+290660	Jabal ThÄnÄ«	Jabal Thani	Jabal Thanais,Jabal Thani,Jabal ThÄnÄ«	25.02249	55.78912	T	HLL	AE		06				0		267	Asia/Dubai	2011-11-06
+290661	Thamūd	Thamud	Thamud,Thamūd	24.78333	55.28333	T	TRGD	AE		03				0		88	Asia/Dubai	2011-11-06
+290662	Barqat ThÄmir	Barqat Thamir	Barqat Thamir,Barqat ThÄmir	23.79619	52.66627	T	DUNE	AE		01				0		74	Asia/Dubai	2011-11-06
+290663	Bid‘at ThallÄb	Bid`at Thallab	Bid`at Thallab,Bid`ath Thalab,Bid‘at ThallÄb,Bid‘ath ThalÄb	23.83333	53.3	H	WLL	AE		01				0		89	Asia/Dubai	2011-11-06
+290664	Ţayyibah	Tayyibah	Taiyibah,Tayibah,Tayiban,Tayyibah,Ţayyibah	25.41228	56.17075	P	PPL	AE		04				0		430	Asia/Dubai	2011-11-06
+290665	Å¢awÄ« Å¢ayy	Tawi Tayy	Tawi Tai,Tawi Tayy,Å¢awÄ« Å¢ayy,Å¢ÄwÄ« Tai	25.23333	55.55	H	WLL	AE		03				0		42	Asia/Dubai	2011-11-06
+290666	Ţawī Ţayrī	Tawi Tayri	Tawi Tayri,Ţawī Ţayrī	25.45472	55.60611	H	WLL	AE		07				0		16	Asia/Dubai	2011-11-06
+290667	Ḩadd aţ Ţayr	Hadd at Tayr	Hadd at Tayr,Ḩadd aţ Ţayr	24.3713	51.83258	H	RF	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290668	Nadd aÅ£ Å¢arÅ«sh	Nadd at Tarush	Nadd Tawsha,Nadd Tawshah,Nadd at Tarush,Nadd aÅ£ Å¢arÅ«sh,Nadd Å¢awshah,Nadd Å¢awshÄ	25.14929	55.37296	T	DUNE	AE		03				0		22	Asia/Dubai	2011-11-06
+290669	WÄdÄ« Å¢awÄ«yayn	Wadi Tawiyayn	Wadi Tawiyayn,WÄdÄ« Å¢awÄ«yayn	25.5575	56.07694	H	WAD	AE		04				0		185	Asia/Dubai	2011-11-06
+290670	Ţawīyayn	Tawiyayn	Tawiyain,Tawiyayn,Tawyayn,Tuwiyain,Ţawīyayn	25.55778	56.07667	H	WLL	AE	AE	04				0		185	Asia/Dubai	2011-11-06
+290671	Ţawī Bin ‘Asīl	Tawi Bin `Asil	Tawi Bin `Asil,Ţawī Bin ‘Asīl	24.20368	54.6095	L	LCTY	AE		01				0		31	Asia/Dubai	2011-11-06
+290672	Ţawī Bid‘ Sa‘īd	Tawi Bid` Sa`id	Tawi Bid` Sa`id,Ţawī Bid‘ Sa‘īd	24.45084	54.74048	T	SAND	AE		01				0		33	Asia/Dubai	2011-11-06
+290673	WÄdÄ« TawÄh	Wadi Tawah	Wadi Tawah,WÄdÄ« TawÄh	24.98978	56.1243	H	WAD	AE		05				0		295	Asia/Dubai	2011-11-06
+290674	Jabal TawÄh	Jabal Tawah	Jabal Tawah,Jabal TawÄh	24.99639	56.12398	T	MT	AE		05				0		306	Asia/Dubai	2011-11-06
+290675	Ţawī Tasharawīyah	Tawi Tasharawiyah	Tawi Tasharawiyah,Ţawī Tasharawīyah	25.28942	55.89526	H	WLL	AE		06				0		105	Asia/Dubai	2011-11-06
+290676	Ţarūqah	Taruqah	Taruqah,Ţarūqah	23.02725	53.88404	T	DPR	AE		01				0		69	Asia/Dubai	2011-11-06
+290677	Ţarūfah	Tarufah	Tarufa,Tarufah,Ţarūfah	23.08936	53.83218	L	OAS	AE		01				0		86	Asia/Dubai	2011-11-06
+290678	Ţawī Tarish	Tawi Tarish	Tawi Tarish,Ţawī Tarish	23.58333	54.61667	H	WLL	AE		01				0		140	Asia/Dubai	2011-11-06
+290679	Ţarīqat Ja‘d	Tariqat Ja`d	Tariqat Ja`d,Ţarīqat Ja‘d	25.52852	56.15144	P	PPL	AE		04				0		357	Asia/Dubai	2011-11-06
+290680	Å¢arÄ«f KalbÄ	Tarif Kalba	Tarif Kalba,Å¢arÄ«f KalbÄ	25.0695	56.33115	P	PPL	AE		06				0		30	Asia/Dubai	2011-11-06
+290681	Ţarīf	Tarif	Al-Tarif,Al-Tarīf,At Tarif,At Turayf,Aţ Ţarīf,Aţ Ţurayf,Taraif,Tarif,Ţarīf	24.05399	53.76347	P	PPL	AE		01				0		24	Asia/Dubai	2011-11-06
+290682	Ţarīf	Tarif	Tarif,Ţarīf	24.03333	53.76667	T	HLL	AE		01				0		13	Asia/Dubai	2011-11-06
+290683	Qurayn aţ Ţarib	Qurayn at Tarib	Qurayn at Tarib,Qurayn aţ Ţarib	25.09414	55.81301	T	HLL	AE		06				0		216	Asia/Dubai	2011-11-06
+290684	Sayḩ Å¢arfÄ’	Sayh Tarfa'	Sayh Tarfa',Sayḩ Å¢arfÄ’	23.21358	55.18286	T	DPR	AE		01				0		154	Asia/Dubai	2011-11-06
+290685	MushÄsh Å¢arfÄ’	Mushash Tarfa'	Mushash Tarfa',MushÄsh Å¢arfÄ’	24.04622	51.69787	H	WLL	AE		01				0		34	Asia/Dubai	2011-11-06
+290686	Qarn at Tarb	Qarn at Tarb	Qarn al Tarab,Qarn at Tarb	24.45094	55.67408	T	HLL	AE		01				0		306	Asia/Dubai	2011-11-06
+290687	Ţaraq	Taraq	Taraq,Tereg,Ţaraq	23.11656	53.60697	P	PPL	AE		01				0		181	Asia/Dubai	2011-11-06
+290688	Å¢arÄhÄ«f	Tarahif	Tarahif,Å¢arÄhÄ«f	22.91769	53.33204	T	DPR	AE		01				0		179	Asia/Dubai	2011-11-06
+290689	WÄdÄ« aÅ£ Å¢araf	Wadi at Taraf	Wadi at Taraf,WÄdÄ« aÅ£ Å¢araf	25.41486	56.32874	H	WAD	AE		04				0		69	Asia/Dubai	2011-11-06
+290690	WÄdÄ« Tarabat	Wadi Tarabat	Wadi Tarabat,WÄdÄ« Tarabat	24.10167	55.71444	H	WAD	AE		01				0		235	Asia/Dubai	2011-11-06
+290691	Tall FÄḩah	Tall Fahah	Tall Fahah,Tall FÄḩah	23.95216	52.35299	L	LCTY	AE		01				0		14	Asia/Dubai	2011-11-06
+290692	Ḩadd aţ Ţallah	Hadd at Tallah	Hadd al Tahlei,Hadd at Tahli,Hadd at Tallah,Hadd at Thalei,Ḩadd at Tahlī,Ḩadd aţ Ţallah	24.66667	54.55	H	SHOL	AE	AE	01				0		-9999	Asia/Dubai	2011-11-06
+290693	Dawḩat Tallah	Dawhat Tallah	Dawhat Tallah,Dawhat Tullah,Dawḩat Tallah,Dawḩat Tullah	24.42605	51.3286	H	BGHT	AE		01				0		1	Asia/Dubai	2011-11-06
+290694	Dawḩat Å¢allÄb	Dawhat Tallab	Dawhat Talab,Dawhat Tallab,Dawhat an Nakhlah,Dawḩat an Nakhlah,Dawḩat Å¢alab,Dawḩat Å¢allÄb,Dohat Tallab,Dohat Tullab,Dohat TullÄb,Dohat an Nakhala,Dohat ṬallÄb,Duhat an Nakhalah	24.2708	51.64849	H	BAY	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290695	Sydney Hill	Sydney Hill	Sydney Hill	24.33333	52.6	T	HLL	AE		01				0		124	Asia/Dubai	2011-11-06
+290696	NaqÄ SuwayÅ£ah	Naqa Suwaytah	Naqa Suwaytah,NaqÄ SuwayÅ£ah	24.34939	55.59034	T	DUNE	AE		01				0		247	Asia/Dubai	2011-11-06
+290697	Å¢awÄ« SuwayḩÄn	Tawi Suwayhan	Tawi Suwayhan,Å¢awÄ« SuwayḩÄn	24.43584	55.25248	H	WLL	AE		01				0		123	Asia/Dubai	2011-11-06
+290698	Sayḩ SuwayḩÄn	Sayh Suwayhan	Sayh Suwayhan,Sayḩ SuwayḩÄn	24.44981	55.28275	H	WAD	AE		01				0		158	Asia/Dubai	2011-11-06
+290699	Ramlat SuwayḩÄn	Ramlat Suwayhan	Ramlat Suwaihan,Ramlat Suwayhan,Ramlat SuwayḩÄn	24.46087	55.26387	T	DUNE	AE		01				0		149	Asia/Dubai	2011-11-06
+290700	Ra’s Suwayfah	Ra's Suwayfah	Ra's Suwayfah,Ra’s Suwayfah	25.59594	56.35239	T	PT	AE		04				0		-9999	Asia/Dubai	2011-11-06
+290701	Farīq Suwayfah	Fariq Suwayfah	Fariq Suwayfah,Farīq Suwayfah	25.59256	56.34525	S	CMP	AE		04				0		60	Asia/Dubai	2011-11-06
+290702	Suwayfah	Suwayfah	Suwayfah	25.59043	56.36261	L	LCTY	AE		04				0		-9999	Asia/Dubai	2011-11-06
+290703	SuwaydÄn	Suwaydan	Suwaydan,SuwaydÄn	25.12436	55.7975	L	AREA	AE		06				0		138	Asia/Dubai	2011-11-06
+290704	WÄdÄ« SuwaydÄ’	Wadi Suwayda'	Wadi Suwayda',WÄdÄ« SuwaydÄ’	24.45696	55.54523	T	TRGD	AE		01				0		261	Asia/Dubai	2011-11-06
+290705	Ţawī SuwaydĒ	Tawi Suwayda'	Tawi Suwayda',Ţawī SuwaydĒ	25.14194	55.29972	H	WLL	AE		03				0		24	Asia/Dubai	2011-11-06
+290706	SuwaydÄ’	Suwayda'	Suwaida,Suwayda',SuwaydÄ’	25.11667	55.3	L	LCTY	AE		03				0		6	Asia/Dubai	2011-11-06
+290707	Sut	Sut	Sut	23.71667	54.53333	H	WLL	AE		01				0		133	Asia/Dubai	2011-11-06
+290708	Surayţ	Surayt	Serait,Surayt,Surayţ	23.12132	53.95075	L	OAS	AE		01				0		94	Asia/Dubai	2011-11-06
+290709	WÄdÄ« SÅ«r	Wadi Sur	Wadi Sur,WÄdÄ« SÅ«r	25.08333	56.36667	H	WAD	AE		06				0		-9999	Asia/Dubai	2011-11-06
+290710	Şūr	Sur	Sur,Şūr	25.09406	56.34827	P	PPL	AE		06				0		23	Asia/Dubai	2011-11-06
+290711	Suqayyah	Suqayyah	Suqayyah	24.57218	55.55891	L	LCTY	AE		01				0		253	Asia/Dubai	2011-11-06
+290712	Sunayyim	Sunayyim	Sunayyim	23.96236	55.40653	T	DUNE	AE		01				0		145	Asia/Dubai	2011-11-06
+290713	Baḩr Sunayţ	Bahr Sunayt	Bahr Sunayt,Baḩr Sunayţ	25.61667	56.25	H	WAD	AE		00				0		7	Asia/Dubai	2011-11-06
+290714	Sumbrair	Sumbrair	Sumbrair,Sumbrayir,Åžumbrayir	25.60082	56.2844	P	PPL	AE		04				0		21	Asia/Dubai	2011-11-06
+290715	Ra’s Sumayrah	Ra's Sumayrah	Ra's Sumayrah,Ras Semaira,Ras Sumaira,Ra’s Sumayrah,RÄs Semaira	24.32243	51.44653	T	PT	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290716	ImshÄsh as Sumayrah	Imshash as Sumayrah	Imshash Semaira,Imshash al-Semeirah,Imshash as Sumayrah,ImshÄsh Semaira,ImshÄsh al-Semeirah,ImshÄsh as Sumayrah,Tawi Sumayrah,Å¢awÄ« Sumayrah	24.27873	51.42068	H	WLL	AE		01				0		51	Asia/Dubai	2011-11-06
+290717	Dawḩat as Sumayrah	Dawhat as Sumayrah	Al Sumaira,Dawhat as Sumayrah,Dawḩat as Sumayrah	24.31884	51.54839	H	BAY	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290718	Sayḩ as Sumayḩ	Sayh as Sumayh	Sayh as Sumayh,Sayḩ as Sumayḩ,Sih al-Semeih,Sih as Semeih,Sih as Sumayh,Sumayh,Sumayḩ,Sīḥ al-Semeiḥ,Sīḩ as Sumayḩ	24.7278	54.78697	T	TRGD	AE		01				0		16	Asia/Dubai	2011-11-06
+290719	Birkat Sumayḩ	Birkat Sumayh	Birkat Sumaih,Birkat Sumayh,Birkat Sumayḩ,Samaih,Semaih,Smeih	24.72276	54.77993	H	WLL	AE		01				0		18	Asia/Dubai	2011-11-06
+290720	Å¢awÄ« SulÅ£Än SÄlim	Tawi Sultan Salim	Tawi Sultan Salim,Å¢awÄ« SulÅ£Än SÄlim	25.02181	55.8195	H	WLL	AE		06				0		170	Asia/Dubai	2011-11-06
+290721	JazÄ«rat aÅŸ ŞīlÄ«yÄ	Jazirat as Siliya	Jazirat Sulayyah,Jazirat as Siliya,JazÄ«rat aÅŸ ŞīlÄ«yÄ,JazÄ«rat Åžulayyah	24.18286	52.8921	T	ISL	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290722	Å¢awÄ« SulaymÄt	Tawi Sulaymat	Al-Seleimat,Al-SeleimÄt,Tawi Sulaymat,Tawi Suleimat,TÄwÄ« Suleimat,Å¢awÄ« SulaymÄt	24.23064	55.59382	H	WLL	AE		01				0		251	Asia/Dubai	2011-11-06
+290723	Sayḩ SulaymÄt	Sayh Sulaymat	Sayh Sulaymat,Sayḩ SulaymÄt	24.19639	55.56278	T	TRGD	AE		01				0		224	Asia/Dubai	2011-11-06
+290724	Sayḩ SulaymÄn	Sayh Sulayman	Sayh Sulayman,Sayḩ SulaymÄn	24.67704	55.47051	T	TRGD	AE		03				0		149	Asia/Dubai	2011-11-06
+290725	Ḩadabat Sukhub	Hadabat Sukhub	Hadabat Sakhub,Hadabat Sukhub,Ḩadabat Sakhub,Ḩadabat Sukhub	24.82094	55.53095	T	DUNE	AE		03				0		157	Asia/Dubai	2011-11-06
+290726	Å¢awÄ« Suhaylah	Tawi Suhaylah	Tawi Saheila,Tawi Suhaylah,Tawi Suheila,TÄwÄ« Saheila,TÄwÄ« Suheila,Å¢awÄ« Suhaylah	25.36667	55.95	H	WLL	AE		07				0		184	Asia/Dubai	2011-11-06
+290727	Suḩaybah	Suhaybah	Suhaybah,Suḩaybah	24.93877	56.15754	P	PPL	AE		05				0		351	Asia/Dubai	2011-11-06
+290728	WÄdÄ« Suftah	Wadi Suftah	Wadi Suftah,WÄdÄ« Suftah	25.46364	56.11519	H	WAD	AE		05				0		297	Asia/Dubai	2011-11-06
+290729	Şufayrī	Sufayri	Sufayri,Şufayrī	24.81168	56.12646	P	PPL	AE		02				0		309	Asia/Dubai	2011-11-06
+290730	Sayḩ Şubrah	Sayh Subrah	Sayh Subrah,Sayḩ Şubrah	24.05023	55.49348	T	TRGD	AE		01				0		196	Asia/Dubai	2011-11-06
+290731	‘Aqabat as Subaykhah	`Aqabat as Subaykhah	`Aqabat as Subaykhah,‘Aqabat as Subaykhah	25.5763	56.33881	T	PASS	AE		04				0		35	Asia/Dubai	2011-11-06
+290732	Subaykhah	Subaykhah	Subaykhah	25.5695	56.33907	L	LCTY	AE		04				0		256	Asia/Dubai	2011-11-06
+290733	Subayḩīyah	Subayhiyah	Subayhiyah,Subayḩīyah	25.40028	56.36417	V	CULT	AE		06				0		-9999	Asia/Dubai	2011-11-06
+290734	Stutter Shoal	Stutter Shoal	Stutter Shoal	24.23777	52.42787	H	SHOL	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290735	Stokes Bluff	Stokes Bluff	Stokes Bluff	24.3	52.63333	T	CLF	AE		01				0		6	Asia/Dubai	2011-11-06
+290736	Mount Stewart	Mount Stewart	Mount Stewart	24.33288	52.59674	T	HLL	AE		01				0		60	Asia/Dubai	2011-11-06
+290737	South YÄsÄt Channel	South Yasat Channel	South Yasat Channel,South YÄsÄt Channel	24.13797	51.98182	H	CHNM	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290738	South Faraydat	South Faraydat	Faraijdat,Fereijid,South Faraydat,South Furayjidat,South FurayjidÄt	24.38333	51.71667	T	ISL	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290740	Å¢awÄ« Sirrah	Tawi Sirrah	Tawi Sirra,Tawi Sirrah,TÄwÄ« Sirra,Å¢awÄ« Sirrah	25.45114	55.61266	H	WLL	AE		07				0		31	Asia/Dubai	2011-11-06
+290741	Şīr Bū Nu‘ayr	Sir Bu Nu`ayr	Jazirat Siri Bu Naybar,Jazīrat Sīrī Bū Naybar,Jezirat Sir Bu Na`air,Jezirat Sir Bu Na‘air,Sir Abu Nu`air,Sir Abu Nu`ayr,Sir Abu Nu‘air,Sir Bu Nu`air,Sir Bu Nu`ayr,Sir bu Na`air Island,Sīr bu Na‘air Island,Şīr Abū Nu‘ayr,Şīr Bū Nu‘ayr,Ṣīr Bū Nu‘air	25.23305	54.2181	T	ISL	AE		01				0		15	Asia/Dubai	2011-11-06
+290742	Şīr BanÄ« YÄs	Sir Bani Yas	Al Yas,Al YÄs,Jezirat Yas,JezÄ«rat Yas,Sir Bani Yas,Sir Banias,Sir Beni Yas,Yas Island,Şīr BanÄ« YÄs	24.32589	52.60128	T	ISL	AE		01				0		124	Asia/Dubai	2011-11-06
+290743	SÄ«rat al Khawr	Sirat al Khawr	Sirat al Khawr,SÄ«rat al Khawr	25.35326	56.37784	T	ISL	AE		04				0		-9999	Asia/Dubai	2011-11-06
+290744	Suwayfat aş Şīr	Suwayfat as Sir	Suwayfat as Sir,Suwayfat aş Şīr	25.5188	56.36949	T	PT	AE		04				0		-9999	Asia/Dubai	2011-11-06
+290746	WÄdÄ« Sinnah	Wadi Sinnah	Wadi Sinnah,WÄdÄ« Sinnah	25.50796	56.19523	H	WAD	AE		04				0		124	Asia/Dubai	2011-11-06
+290747	Sinnah	Sinnah	Sinnah	25.50868	56.16772	P	PPL	AE		04				0		198	Asia/Dubai	2011-11-06
+290748	SinÄdil	Sinadil	Sinadil,SinÄdil	24.81095	56.02511	P	PPL	AE		02				0		424	Asia/Dubai	2011-11-06
+290749	Nada Sima	Nada Sima	Nada Sima	24.18333	55.36667	T	DUNE	AE		01				0		198	Asia/Dubai	2011-11-06
+290750	Ra’s as Silmīyah	Ra's as Silmiyah	Ra's as Silmiyah,Ra’s as Silmīyah	24.25278	54.52889	T	DUNE	AE		01				0		8	Asia/Dubai	2011-11-06
+290751	Silmīyah	Silmiyah	Silmiya,Silmiyah,Silmīya,Silmīyah	24.2	54.35	T	HLL	AE	AE	01				0		6	Asia/Dubai	2011-11-06
+290752	Silmīyah	Silmiyah	Al-Silaimiyyah,Silmiyah,Silmīyah	24.22404	54.46374	T	DUNE	AE		01				0		13	Asia/Dubai	2011-11-06
+290753	Sayḩ Silm	Sayh Silm	Sayh Silm,Sayḩ Silm	24.41779	55.31025	T	TRGD	AE		01				0		158	Asia/Dubai	2011-11-06
+290754	Jabal Silḩū Bilḩū	Jabal Silhu Bilhu	Jabal Silhu Bilhu,Jabal Silḩū Bilḩū	25.15146	56.06771	T	MT	AE		05				0		607	Asia/Dubai	2011-11-06
+290755	Ra’s as Sila‘	Ra's as Sila`	Ra's as Sil`,Ra's as Sila`,Ra’s as Sila‘,Ra’s as Sil‘	24.05	51.78333	T	PT	AE		01				0		1	Asia/Dubai	2011-11-06
+290756	Dawḩat as Sila‘	Dawhat as Sila`	Dawhat as Sila`,Dawḩat as Sila‘	23.96667	51.93333	H	INLT	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290757	WÄdÄ« SÄ«jÄ«	Wadi Siji	Wadi Nakh,Wadi Siji,Wadi as Siji,WÄdÄ« Nakh,WÄdÄ« SÄ«jÄ«,WÄdÄ« as SÄ«jÄ«	25.2736	56.03543	H	WAD	AE		00				0		225	Asia/Dubai	2011-11-06
+290758	Jabal Sījī	Jabal Siji	Jabal Siji,Jabal Sījī	25.2436	56.12194	T	MT	AE		04				0		664	Asia/Dubai	2011-11-06
+290759	Tawi Siji	Tawi Siji	Siji,Sījī,Tawi Siji,Tawi as Siji,Ţawī as Sījī	25.24764	56.07719	P	PPL	AE		04				0		324	Asia/Dubai	2011-11-06
+290760	Wadi Saha	Wadi Saha	Wadi Saha,Wadi Siha',WÄdÄ« ÅžihÄ’	25.3828	56.29541	H	WAD	AE		00				0		320	Asia/Dubai	2011-11-06
+290761	Jabal ÅžihÄ’	Jabal Siha'	Jabal Siha',Jabal ÅžihÄ’	25.33931	56.276	T	MT	AE		00				0		788	Asia/Dubai	2011-11-06
+290762	WÄdÄ« SifÅ«nÄ«	Wadi Sifuni	Wadi Sifuni,WÄdÄ« SifÅ«nÄ«	25.19333	56.01389	H	WAD	AE		05				0		189	Asia/Dubai	2011-11-06
+290763	Sayḩ as Sidrah	Sayh as Sidrah	Sayh Sadrah,Sayh as Sidrah,Sayḩ Sadrah,Sayḩ as Sidrah,Sidra,Sih as Sidrah,Sīḩ as Sidrah	24.81824	54.9264	T	TRGD	AE		01				0		31	Asia/Dubai	2011-11-06
+290764	WÄdÄ« Sidr	Wadi Sidr	Wadi Sidr,WÄdÄ« Sidr	25.42182	56.09854	H	WAD	AE		04				0		290	Asia/Dubai	2011-11-06
+290765	Jabal Sidr	Jabal Sidr	Jabal Sidr	25.36833	56.34	T	HLL	AE		06				0		11	Asia/Dubai	2011-11-06
+290766	WÄdÄ« Sadakh	Wadi Sadakh	Wadi Sadakh,Wadi Sidakh,WÄdÄ« Sadakh,WÄdÄ« Sidakh	25.56929	56.06399	H	WAD	AE		04				0		132	Asia/Dubai	2011-11-06
+290767	SÄ«bat al AshkharÄt	Sibat al Ashkharat	Sibat al Ashkharat,SÄ«bat al AshkharÄt	25.61667	56.26667	S	CMTY	AE		04				0		19	Asia/Dubai	2011-11-06
+290768	WÄdÄ« Shuway	Wadi Shuway	Wadi Shuway,Wadi Shuwayy,WÄdÄ« Shuway,WÄdÄ« Shuwayy	25.23142	56.20244	H	WAD	AE		04				0		233	Asia/Dubai	2011-11-06
+290769	WÄdÄ« Shuways	Wadi Shuways	Wadi Shuways,WÄdÄ« Shuways	25.18957	56.33323	H	WAD	AE		04				0		347	Asia/Dubai	2011-11-06
+290770	Jabal Shuways	Jabal Shuways	Jabal Shuways	25.17617	56.3459	T	HLL	AE		04				0		171	Asia/Dubai	2011-11-06
+290771	Al Quwayz	Al Quwayz	Al Quwayz,Chuwais,Kuways,Shuways	25.78102	55.9787	P	PPLX	AE		05				0		24	Asia/Dubai	2011-11-06
+290772	JazÄ«rat ShuwayhÄt	Jazirat Shuwayhat	Jazirat Mashat,Jazirat Showayhat,Jazirat Shuwayhat,JazÄ«rat Mashat,JazÄ«rat ShowayhÄt,JazÄ«rat ShuwayhÄt,Shuwaihat,ShuwaihÄt,Shuweihat,ShuweihÄt	24.11391	52.43972	T	ISL	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290773	Bid‘ Shuwaybir	Bid` Shuwaybir	Bid` Shuwaybir,Bida` Shuwaibah,Bidau' Shuaibar,Bidau' Suaibar,Bidau’ Shuaibar,Bidau’ Suaibar,Bida‘ Shuwaibah,Bid‘ Shuwaybir,Budu` Shuaibar,Budu` Shuwaibir,Budu` Shuwaybir,Budu‘ Shuwaibir,Budū‘ Shuaibar,Budū‘ Shuwaybir,Shawaibir	24.0958	54.58919	H	WLL	AE		01				0		46	Asia/Dubai	2011-11-06
+290774	Shū Triyyah	Shu Triyyah	Shu Triyyah,Shū Triyyah	24.24938	54.29978	T	ISL	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290775	Shuray‘ah	Shuray`ah	Shuray`ah,Shuray‘ah	24.3	53.61667	T	ISL	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290776	Shunayyin	Shunayyin	Shunayyin	24.05604	54.46374	T	SAND	AE		01				0		39	Asia/Dubai	2011-11-06
+290777	Shunayyin	Shunayyin	Shunayyin	24.10632	54.39287	L	LCTY	AE		01				0		16	Asia/Dubai	2011-11-06
+290778	Shunayyin	Shunayyin	Shinaiyin,Shunaiyin,Shunayyin	24.21667	54.41667	T	HLL	AE	AE	01				0		3	Asia/Dubai	2011-11-06
+290779	Buday‘ Shumrūkh	Buday` Shumrukh	Buday` Shumrukh,Buday‘ Shumrūkh,Shumrukh,Shumrūkh	24.77232	55.7849	H	WLL	AE		01				0		302	Asia/Dubai	2011-11-06
+290780	Sayḩ Shumayrīkh	Sayh Shumayrikh	Sayh Shumayrikh,Sayḩ Shumayrīkh	24.71557	55.4203	T	TRGD	AE		03				0		145	Asia/Dubai	2011-11-06
+290781	Shumaylīyah	Shumayliyah	Ash Shumailiya,Ash Shumailīya,Ash Shumayliyah,Ash Shumaylīyah,Shamailiya,Shamailiyah,Shamailīyah,Shamayliyah,Shamaylīyah,Shumailiyah,Shumayliyah,Shumaylīyah	25.33333	56.33333	L	AREA	AE	AE	06				0		426	Asia/Dubai	2011-11-06
+290782	Jabal Shughayr	Jabal Shughayr	Jabal Shughayr	25.4	56.33333	T	HLL	AE		04				0		55	Asia/Dubai	2011-11-06
+290783	Ţawī Shubayşī	Tawi Shubaysi	Tawi Shubaysi,Ţawī Shubayşī	24.16278	55.05729	H	WLL	AE		01				0		120	Asia/Dubai	2011-11-06
+290784	Nadd ash ShibÄ	Nadd ash Shiba	Nad Shibeih,Nadd Shubayh,Nadd Shubayḩ,Nadd ash Shiba,Nadd ash ShibÄ	25.14583	55.33417	P	PPL	AE	AE	03				0		23	Asia/Dubai	2011-11-06
+290785	Shu‘ayb ‘Ūd	Shu`ayb `Ud	Shu`ayb `Ud,Shu‘ayb ‘Ūd	24.74968	55.79034	V	TREE	AE		00				0		253	Asia/Dubai	2011-11-06
+290786	Shu‘ayb Şaghīr	Shu`ayb Saghir	Shu`ayb Saghir,Shu‘ayb Şaghīr	24.74944	55.82028	V	TREE	AE		01				0		311	Asia/Dubai	2011-11-06
+290787	Sayḩ Shu‘ayb	Sayh Shu`ayb	Sayh Shu`ayb,Sayh ash Shu`ayb,Sayḩ Shu‘ayb,Sayḩ ash Shu‘ayb,Shu`aib,Shu‘aib,Sih Shu`aib,Sīḩ Shu‘aib	24.89786	54.96311	T	TRGD	AE		00				0		17	Asia/Dubai	2011-11-06
+290788	Raml ash Shu‘ayb	Raml ash Shu`ayb	Raml ash Shu`ayb,Raml ash Shu‘ayb	24.8757	55.0429	T	SAND	AE		03				0		30	Asia/Dubai	2011-11-06
+290789	Shīshah	Shishah	Shisha,Shishah,Shīshah	24.33635	54.94465	T	HLL	AE		01				0		65	Asia/Dubai	2011-11-06
+290790	WÄdÄ« ShÄ«ÅŸah	Wadi Shisah	Wadi Shisa,Wadi Shisah,WÄdÄ« ShÄ«ÅŸah	25.84028	56.1	H	WAD	AE	AE	05				0		321	Asia/Dubai	2011-11-06
+290791	Ramlat Shīşah	Ramlat Shisah	Ramlat Shisah,Ramlat Shīşah	25.38835	56.02995	T	DUNE	AE		04				0		304	Asia/Dubai	2011-11-06
+290792	WÄdÄ« ShÄ«s	Wadi Shis	Wadi Shis,WÄdÄ« ShÄ«s	25.29348	56.24396	H	WAD	AE		06				0		408	Asia/Dubai	2011-11-06
+290793	Shīs	Shis	Shis,Shīs	25.29138	56.24549	P	PPL	AE		06				0		365	Asia/Dubai	2011-11-06
+290794	WÄdÄ« ShimÄl	Wadi Shimal	Wadi Shimal,WÄdÄ« ShimÄl	25.50089	56.18876	H	WAD	AE		04				0		158	Asia/Dubai	2011-11-06
+290795	ShimÄl	Shimal	Shimal,Shimil,ShimÄl	25.8178	56.01088	P	PPL	AE		05				0		19	Asia/Dubai	2011-11-06
+290796	Khaţmat ash Shiklah	Khatmat ash Shiklah	Khaim ash Shikla,Khatm al-Shiklah,Khatmat ash Shiklah,Khaţmat ash Shiklah,Khaṭm al-Shiklah	24.21583	55.95306	T	SPUR	AE	AE	01				0		392	Asia/Dubai	2011-11-06
+290797	Shidq al Kalb	Shidq al Kalb	Shidq al Kalb,Shudeg al-Kalb,Shudq al Kalb	23.13385	53.73315	L	OAS	AE		01				0		93	Asia/Dubai	2011-11-06
+290798	WÄdÄ« ShibḩÄt	Wadi Shibhat	Wadi Shibhat,WÄdÄ« ShibḩÄt	24.45849	55.7685	T	TRGD	AE		01				0		321	Asia/Dubai	2011-11-06
+290799	Shabahanat al Majann	Shabahanat al Majann	Ash Shibhanah,Shabahanat al Majann,Shibhanat al Mijann,ShibhÄnat al Mijann	24.01997	51.735	T	PLAT	AE		01				0		48	Asia/Dubai	2011-11-06
+290800	ShibÄnÄt	Shibanat	Shibanat,ShibÄnÄt	24.91667	55.66667	L	TRB	AE		00				0		190	Asia/Dubai	2011-11-06
+290801	Shi‘b al GhÄf	Shi`b al Ghaf	Shi`b al Ghaf,Shib al Gat,Shi‘b al GhÄf	24.05278	55.71972	P	PPL	AE		01				0		237	Asia/Dubai	2011-11-06
+290802	ShibÄk	Shibak	Shibak,ShibÄk	24.59856	55.52346	L	LCTY	AE		01				0		208	Asia/Dubai	2011-11-06
+290803	Jabal Shi‘Äb ash Shaybah	Jabal Shi`ab ash Shaybah	Jabal Sha`ab ash Shaybah,Jabal Sha‘Äb ash Shaybah,Jabal Shi`ab ash Shaybah,Jabal Shi‘Äb ash Shaybah	25.40026	56.30431	T	MT	AE		04				0		410	Asia/Dubai	2011-11-06
+290804	WÄdÄ« ShÄ«	Wadi Shi	Wadi Shi,WÄdÄ« ShÄ«	25.34983	56.35746	H	WAD	AE		06				0		40	Asia/Dubai	2011-11-06
+290805	Shaykh ad DimÄth	Shaykh ad Dimath	Shaikh al Dimath,Shaykh ad Dimath,Shaykh ad DimÄth	24.01056	53.09528	L	LCTY	AE	AE	01				0		29	Asia/Dubai	2011-11-06
+290806	Shaydad Bin Khanfūr	Shaydad Bin Khanfur	Shaydad Bin Khanfur,Shaydad Bin Khanfūr	24.6932	55.44164	T	SAND	AE		03				0		141	Asia/Dubai	2011-11-06
+290807	‘Urūq ash Shaybah	`Uruq ash Shaybah	Uruq ash Shaibah,Uruq ash Sheibah,`Uruq ash Shaybah,‘Urūq ash Shaybah	22.35	54.91667	T	DUNE	AE		01				0		161	Asia/Dubai	2011-11-06
+290808	Sayḩ Shawyī	Sayh Shawyi	Sayh Shawyi,Sayḩ Shawyī	25.65293	56.01207	T	PLN	AE		05				0		17	Asia/Dubai	2011-11-06
+290809	WÄdÄ« Shawkah	Wadi Shawkah	Wadi Shaukha,Wadi Shawkah,WÄdÄ« Shawkah	25.26761	55.8668	H	WAD	AE		06				0		110	Asia/Dubai	2011-11-06
+290810	Ţawī Shawkah	Tawi Shawkah	Tawi Shawkah,Ţawī Shawkah	25.03056	56.10694	H	WLL	AE		05				0		699	Asia/Dubai	2011-11-06
+290811	Jabal Shawkah	Jabal Shawkah	Jabal Shauka,Jabal Shawkah	25.10014	56.04331	T	HLL	AE		05				0		442	Asia/Dubai	2011-11-06
+290812	Shawkah	Shawkah	Shauka,Shawkah,Shokah	25.1	56.03333	P	PPL	AE	AE	05				0		283	Asia/Dubai	2011-11-06
+290813	WÄdÄ« Shawiyayn	Wadi Shawiyayn	Wadi Shawiyayn,WÄdÄ« Shawiyayn	25.27208	56.06068	H	WAD	AE		04				0		247	Asia/Dubai	2011-11-06
+290814	Shawīyah	Shawiyah	Shawiyah,Shawīyah	25.26792	56.08149	P	PPL	AE		04				0		304	Asia/Dubai	2011-11-06
+290815	Å¢awÄ« ShÄÅ£	Tawi Shat	Tawi Shat,Å¢awÄ« ShÄÅ£	24.48333	55.2	H	WLLQ	AE		01				0		139	Asia/Dubai	2011-11-06
+290816	ShÄt	Shat	Shat,ShÄt	24.48614	55.19806	T	SAND	AE		01				0		117	Asia/Dubai	2011-11-06
+290817	Sharqīyīn	Sharqiyin	Sharqiyan,Sharqiyin,Sharqīyīn	25.25	56.16667	L	TRB	AE	AE	00				0		522	Asia/Dubai	2011-11-06
+290818	Å¢awÄ« SharqÄn	Tawi Sharqan	Tawi Sharqan,Å¢awÄ« SharqÄn	25.38333	55.4	H	WLL	AE		06				0		1	Asia/Dubai	2011-11-06
+290819	Jabal Sharmah	Jabal Sharmah	Jabal Sharmah	25.28406	56.12845	T	MT	AE		04				0		594	Asia/Dubai	2011-11-06
+290820	Sharm	Sharm	Sharam,Sharm	25.47078	56.35319	P	PPL	AE		04				0		14	Asia/Dubai	2011-11-06
+290821	Jabal Sharīyah	Jabal Shariyah	Jabal Shariyah,Jabal Sharīyah	25.29063	56.14987	T	MT	AE		04				0		415	Asia/Dubai	2011-11-06
+290822	Sharīyah	Shariyah	Shariyah,Sharīyah	25.1	56.03333	P	PPL	AE		05				0		283	Asia/Dubai	2011-11-06
+290823	Sharīyah	Shariyah	Shariyah,Sharīyah	24.81512	56.0986	P	PPL	AE		02				0		319	Asia/Dubai	2011-11-06
+290824	Khawr ash ShÄriqah	Khawr ash Shariqah	Khawr ash Shariqah,Khawr ash ShÄriqah,Khor Sharja,Khor Sharjah,Khor ShÄrja	25.33111	55.38222	H	INLT	AE	AE	06				0		9	Asia/Dubai	2011-11-06
+290825	Sayḩ Sharbū	Sayh Sharbu	Sayh Sharbu,Sayḩ Sharbū	24.81667	55.41667	T	TRGD	AE		03				0		125	Asia/Dubai	2011-11-06
+290826	Raml Sharbū	Raml Sharbu	Raml Sharbu,Raml Sharbū	24.83333	55.41667	T	SAND	AE		03				0		130	Asia/Dubai	2011-11-06
+290827	Sharaf Tamī	Sharaf Tami	Sharaf Tami,Sharaf Tamī	23.62836	55.33692	T	DUNE	AE		01				0		207	Asia/Dubai	2011-11-06
+290828	Sharaf Sawqar	Sharaf Sawqar	Sharaf Sawqar	24.33333	55.7	L	LCTY	AE		01				0		275	Asia/Dubai	2011-11-06
+290829	Sharaf Mundassah	Sharaf Mundassah	Sharaf Mundassah	24.58472	55.73722	V	TREE	AE		01				0		308	Asia/Dubai	2011-11-06
+290830	Sharaf JabÄrah	Sharaf Jabarah	Sharaf Jabara,Sharaf Jabarah,Sharaf JabÄrah	24.62804	55.77334	L	LCTY	AE		01				0		337	Asia/Dubai	2011-11-06
+290831	Sharaf Ḩawrah	Sharaf Hawrah	Sharaf Hawrah,Sharaf Ḩawrah	24.54521	55.71675	T	SAND	AE		01				0		318	Asia/Dubai	2011-11-06
+290832	Sharaf á¸abbah	Sharaf Dabbah	Sharaf Dabbah,Sharaf á¸abbah	24.55321	55.65638	L	LCTY	AE		01				0		288	Asia/Dubai	2011-11-06
+290833	Sharaf Bin ‘Ubayd	Sharaf Bin `Ubayd	Sharaf Bin `Ubayd,Sharaf Bin ‘Ubayd	24.91667	55.4	L	LCTY	AE		03				0		100	Asia/Dubai	2011-11-06
+290834	Sharaf al ‘AfÄr	Sharaf al `Afar	Sharaf al `Afar,Sharaf al ‘AfÄr	24.9516	55.44056	L	LCTY	AE		03				0		85	Asia/Dubai	2011-11-06
+290835	WÄdÄ« SharabÄt	Wadi Sharabat	Wadi Sharabat,WÄdÄ« SharabÄt	24.88063	56.21317	H	WAD	AE		05				0		142	Asia/Dubai	2011-11-06
+290836	Jabal Sharab	Jabal Sharab	Jabal Sharab	25.0138	56.0337	T	MT	AE		05				0		664	Asia/Dubai	2011-11-06
+290837	Jabal Sha‘rÄ’	Jabal Sha`ra'	Jabal Sha`arah,Jabal Sha`ra',Jabal Sha‘arah,Jabal Sha‘rÄ’	24.06667	56.26667	T	MT	AE		01				0		995	Asia/Dubai	2011-11-06
+290838	WÄdÄ« Shaqq	Wadi Shaqq	Wadi Shaq,Wadi Shaqq,WÄdÄ« Shaqq	25.84389	56.02139	H	WAD	AE	AE	05				0		26	Asia/Dubai	2011-11-06
+290839	Ţawī Shaqq	Tawi Shaqq	Tawi Shaqq,Ţawī Shaqq	24.38244	55.60894	H	WLL	AE		01				0		232	Asia/Dubai	2011-11-06
+290840	Ramlat Shanţūt Bin ‘UmÄn	Ramlat Shantut Bin `Uman	Ramlat Shantut Bin `Uman,Ramlat Shanţūt Bin ‘UmÄn	24.26667	55.4	T	DUNE	AE		01				0		195	Asia/Dubai	2011-11-06
+290841	Shanţūt Ibn ‘UmÄn	Shantut Ibn `Uman	Shantut Bin `Uman,Shantut Ibn `Uman,Shanţūt Bin ‘UmÄn,Shanţūt Ibn ‘UmÄn	24.25432	55.42166	T	TRGD	AE		01				0		183	Asia/Dubai	2011-11-06
+290842	Shanţūţ	Shantut	Shantut,Shanţūţ	23.38142	55.30225	T	DUNE	AE		01				0		154	Asia/Dubai	2011-11-06
+290843	Shantuba	Shantuba	Shantuba	24.54867	55.73806	L	LCTY	AE		01				0		322	Asia/Dubai	2011-11-06
+290844	Ra’s Shandaghah	Ra's Shandaghah	Ra's Shandaghah,Ra’s Shandaghah	25.26667	55.28333	T	PT	AE		03				0		-9999	Asia/Dubai	2011-11-06
+290845	Shandaghah	Shandaghah	Shandaghah	25.25833	55.28333	P	PPLX	AE		03				0		9	Asia/Dubai	2011-11-06
+290846	‘Araj Shamsī	`Araj Shamsi	`Araj Shamsi,‘Araj Shamsī	24.18944	54.70361	T	DPR	AE		01				0		51	Asia/Dubai	2011-11-06
+290847	ShammÄmÄ«yah	Shammamiyah	Shammamiyah,ShammÄmÄ«yah	23.06374	53.68898	T	DPR	AE		01				0		76	Asia/Dubai	2011-11-06
+290848	ShÄmis	Shamis	Shamis,Shams,ShÄmis	23.93333	53.7	L	GASF	AE	AE	01				0		21	Asia/Dubai	2011-11-06
+290849	ShÄmis	Shamis	Shamis,ShÄmis	23.93854	53.69593	S	FCL	AE		01				0		41	Asia/Dubai	2011-11-06
+290851	WÄdÄ« ash ShÄmah	Wadi ash Shamah	Wadi ash Shamah,WÄdÄ« ash ShÄmah	25.41592	56.33835	H	WAD	AE		00				0		36	Asia/Dubai	2011-11-06
+290852	WÄdÄ« ash Sha‘m	Wadi ash Sha`m	Wadi ash Sha`m,WÄdÄ« ash Sha‘m	26.03111	56.0975	H	WAD	AE		05				0		143	Asia/Dubai	2011-11-06
+290853	WÄdÄ« ash ShÄl	Wadi ash Shal	Wadi ash Shal,WÄdÄ« ash ShÄl	25.38365	55.95383	H	WAD	AE		07				0		155	Asia/Dubai	2011-11-06
+290854	WÄdÄ« Shakhkh	Wadi Shakhkh	Wadi Shakh,Wadi Shakhkh,WÄdÄ« Shakh,WÄdÄ« Shakhkh	25.58769	56.14287	H	WAD	AE		04				0		228	Asia/Dubai	2011-11-06
+290855	Haḑbat Shakhbūţ	Hadbat Shakhbut	Hadbat Shakhbut,Haḑbat Shakhbūţ	24.29583	54.65722	T	HLL	AE		01				0		27	Asia/Dubai	2011-11-06
+290856	Shaitham	Shaitham	Shaitham,Shaithan,ShaithÄn	24.29326	54.85926	H	WLL	AE		01				0		71	Asia/Dubai	2011-11-06
+290857	Sayḩ Sha‘īl	Sayh Sha`il	Sayh Sha`il,Sayḩ Sha‘īl	24.68333	55.45	T	TRGD	AE		03				0		160	Asia/Dubai	2011-11-06
+290858	Qarn ShÄ’i‘	Qarn Sha'i`	Qarn Sha'i`,Qarn ShÄ’i‘	23.83933	53.28344	T	HLL	AE		01				0		91	Asia/Dubai	2011-11-06
+290859	Å¢awÄ« ShÄhÄ«n	Tawi Shahin	Tawi Shahin,Å¢awÄ« ShÄhÄ«n	25.61667	55.88333	H	WLL	AE		05				0		93	Asia/Dubai	2011-11-06
+290860	ShahawÄt	Shahawat	Sahawat,Shahawat,ShahawÄt	25.96667	56.08333	P	PPL	AE	AE	05				0		18	Asia/Dubai	2011-11-06
+290861	ShahÄ’irah	Shaha'irah	Shaha'irah,ShahÄ’irah	25.38333	56.13333	L	TRB	AE		05				0		501	Asia/Dubai	2011-11-06
+290862	WÄdÄ« ShÄh	Wadi Shah	Wadi Shah,WÄdÄ« ShÄh	25.82949	56.10949	H	WAD	AE		05				0		202	Asia/Dubai	2011-11-06
+290863	ShÄh	Shah	Shah,ShÄh	23.13561	53.91652	P	PPL	AE		01				0		170	Asia/Dubai	2011-11-06
+290864	ShÄh	Shah	Shah,ShÄh	22.85	53.91667	L	OILF	AE		01				0		170	Asia/Dubai	2011-11-06
+290865	ShÄh	Shah	Shah,ShÄh	23.13333	53.91667	T	DPR	AE		01				0		158	Asia/Dubai	2011-11-06
+290866	ShÄh	Shah	Shah,ShÄh	25.89861	56.12833	P	PPL	AE		05				0		715	Asia/Dubai	2011-11-06
+290867	Shabqatayn	Shabqatayn	Shabqatayn	23.91665	55.20997	T	DUNE	AE		01				0		178	Asia/Dubai	2011-11-06
+290868	Sha‘bīyah	Sha`biyah	Sha`biya,Sha`biyah,Sha‘biya,Sha‘bīyah	24.28333	54.48333	T	HLL	AE		01				0		12	Asia/Dubai	2011-11-06
+290869	Shabakah	Shabakah	Shabakah	25.03333	56	P	PPL	AE		05				0		322	Asia/Dubai	2011-11-06
+290870	WÄdÄ« Shabak	Wadi Shabak	Wadi Shabak,WÄdÄ« Shabak	25.15157	55.45444	T	TRGD	AE		03				0		22	Asia/Dubai	2011-11-06
+290871	Bid‘ Shabaan	Bid` Shabaan	Bid` Shabaan,Bid‘ Shabaan	23.35	54.36667	H	WLL	AE		01				0		133	Asia/Dubai	2011-11-06
+290872	Sha‘athÄn	Sha`athan	Sha`athan,Sha‘athÄn	24.27375	54.91292	T	SAND	AE		01				0		73	Asia/Dubai	2011-11-06
+290873	WÄdÄ« Sha‘arah	Wadi Sha`arah	Wadi Sha`arah,Wadi Sha`areh,WÄdÄ« Sha‘arah,WÄdÄ« Sha‘areh	25.06667	56.36667	H	WAD	AE		06				0		-9999	Asia/Dubai	2011-11-06
+290874	Sayyidah	Sayyidah	Sayyidah	24.6884	55.70747	V	TREE	AE		01				0		281	Asia/Dubai	2011-11-06
+290875	Ramlat Sayyid	Ramlat Sayyid	Ramlat Saiyin,Ramlat Sayyid,Ramle Sayyid	24.39496	55.60754	T	DUNE	AE		01				0		304	Asia/Dubai	2011-11-06
+290876	WÄdÄ« Sayraq	Wadi Sayraq	Wadi Sayraq,WÄdÄ« Sayraq	25.56185	56.05472	H	WAD	AE		04				0		127	Asia/Dubai	2011-11-06
+290877	Sayḩ MaḩÄrÄ«	Sayh Mahari	Sayh Mahari,Sayḩ MaḩÄrÄ«	25.38333	55.73333	T	DUNE	AE		06				0		51	Asia/Dubai	2011-11-06
+290878	Sayḩ aş Şaqlah	Sayh as Saqlah	Sayh as Saqlah,Sayḩ aş Şaqlah	24.88398	56.16847	P	PPL	AE		05				0		195	Asia/Dubai	2011-11-06
+290879	Sayḩ al Ḩalamah	Sayh al Halamah	Sayh al Halamah,Sayh al Halmah,Sayḩ al Ḩalamah,Sayḩ al Ḩalmah	24.25409	54.6919	T	DPR	AE		01				0		22	Asia/Dubai	2011-11-06
+290880	Sayḩ	Sayh	Sayh,Sayḩ	25.93333	56.06667	P	PPL	AE		05				0		196	Asia/Dubai	2011-11-06
+290881	Ţawī Sayfilman	Tawi Sayfilman	Tawi Sayfilman,Ţawī Sayfilman	23.6	54.6	H	WLL	AE		01				0		113	Asia/Dubai	2011-11-06
+290882	Ţawī Sayf	Tawi Sayf	Tawi Sayf,Ţawī Sayf	25.33472	55.81056	H	WLL	AE		06				0		79	Asia/Dubai	2011-11-06
+290883	Bid‘ Sayf	Bid` Sayf	Bid` Sayf,Bid‘ Sayf	25.06667	55.58333	H	WLL	AE		03				0		107	Asia/Dubai	2011-11-06
+290884	Bid‘ Sayf	Bid` Sayf	Bid` Sayf,Bid‘ Sayf	23.9195	54.93082	T	DPR	AE		01				0		105	Asia/Dubai	2011-11-06
+290885	Barqat Sayf	Barqat Sayf	Barqat Sayf,Burga Seif,Burqat Sayf	24.29874	52.58478	T	HLL	AE		01				0		34	Asia/Dubai	2011-11-06
+290886	Barqat Sayf	Barqat Sayf	Barqat Sayf	24.03307	53.27185	T	HLL	AE		01				0		14	Asia/Dubai	2011-11-06
+290887	WÄdÄ« SaybitalmÄ	Wadi Saybitalma	Wadi Saybitalma,WÄdÄ« SaybitalmÄ	25.23589	56.13664	H	WAD	AE		05				0		437	Asia/Dubai	2011-11-06
+290888	NaqÄ SawÅ£ah	Naqa Sawtah	Naqa Sawtah,NaqÄ SawÅ£ah	24.26611	55.55694	T	DUNE	AE		01				0		197	Asia/Dubai	2011-11-06
+290889	Jabal SawdÄ’	Jabal Sawda'	Jaba Sawda',Jaba SawdÄ’,Jabal Sawda',Jabal SawdÄ’	25.20083	56.33993	T	HLL	AE		04				0		377	Asia/Dubai	2011-11-06
+290890	Ra’s Abyaḑ QaÅ£Ä	Ra's Abyad Qata	Ra's Abyad Qata,Ra's Sawami`,Ra’s Abyaḑ QaÅ£Ä,Ra’s ÅžawÄmi‘	24.14785	53.20015	T	PT	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290891	Jabal SÄÅ£if	Jabal Satif	Jabal Satif,Jabal SÄÅ£if	25.49887	56.04789	T	MT	AE		04				0		374	Asia/Dubai	2011-11-06
+290892	Saţḩ ar RÄzbÅ«t	Sath ar Razbut	Saath al Raazboot,Satah,Sath ar Razbut,Saţḩ ar RÄzbÅ«t	24.83333	53.16667	L	OILF	AE	AE	01				0		-9999	Asia/Dubai	2011-11-06
+290893	SarÅ«q ZÄhir	Saruq Zahir	Saruq Zahir,SarÅ«q ZÄhir	24.21007	54.69939	H	SBKH	AE		01				0		32	Asia/Dubai	2011-11-06
+290894	Sarūq al Jasam	Saruq al Jasam	Saruq al Jasam,Sarūq al Jasam	24.55	55.43333	T	DUNE	AE		01				0		181	Asia/Dubai	2011-11-06
+290895	SÄrÅ«q	Saruq	Saruq,SÄrÅ«q	23.04905	53.73279	T	DPR	AE		01				0		75	Asia/Dubai	2011-11-06
+290896	Sarūj	Saruj	Saruj,Sarūj	25.26636	56.30934	P	PPL	AE		00				0		386	Asia/Dubai	2011-11-06
+290897	Sarūb	Sarub	Sarub,Sarūb	23.07561	53.69655	T	DPR	AE		01				0		164	Asia/Dubai	2011-11-06
+290898	Sayḩ Şarm Sayf	Sayh Sarm Sayf	Sayh Sarm Sayf,Sayḩ Şarm Sayf	23.68333	55.48333	T	DPR	AE		01				0		183	Asia/Dubai	2011-11-06
+290899	Ţawī ŞarmĒ	Tawi Sarma'	Tawi Saramin,Tawi Sarma',Tawi Sarmah,Ţawī Şaramin,Ţawī Şarmah,Ţawī ŞarmĒ	24.98018	55.88064	H	WLL	AE		06				0		203	Asia/Dubai	2011-11-06
+290900	Wuqnat Sarīj	Wuqnat Sarij	Wuqnat Sarij,Wuqnat Sarīj	22.97483	53.77287	T	DPR	AE		01				0		55	Asia/Dubai	2011-11-06
+290901	SarÄmÄ«	Sarami	Sarami,SarÄmÄ«	24.1	54.51667	T	HLL	AE		01				0		33	Asia/Dubai	2011-11-06
+290902	Ţawī Şaram	Tawi Saram	Sarm,Tawi Saram,Şarm,Ţawī Şaram	25.4925	56.02583	H	WLL	AE	AE	05				0		114	Asia/Dubai	2011-11-06
+290903	Ra’s Sarab	Ra's Sarab	Ra's Sarab,Ras as-Sareb,Ra’s Sarab,RÄs as-Sareb	24.26252	51.78124	T	PT	AE		01				0		17	Asia/Dubai	2011-11-06
+290904	ÅžaqwÄn	Saqwan	Saqwan,ÅžaqwÄn	23.76608	53.49031	L	GVL	AE		01				0		105	Asia/Dubai	2011-11-06
+290905	MÄ«nÄ’ Åžaqr	Mina' Saqr	Mina Saqr Harbour,Mina' Saqr,MÄ«nÄ’ Åžaqr,Port Saqr	25.79167	55.95333	H	HBR	AE		05				0		-9999	Asia/Dubai	2011-11-06
+290906	WÄdÄ« Saqamqam	Wadi Saqamqam	Wadi Saqamqam,WÄdÄ« Saqamqam	25.16667	56.33333	H	WAD	AE		04				0		160	Asia/Dubai	2011-11-06
+290907	Sabkhat Saqamqam	Sabkhat Saqamqam	Sabkhat Saqamqam	25.15839	56.35618	H	SBKH	AE		04				0		16	Asia/Dubai	2011-11-06
+290908	Jabal Saqamqam	Jabal Saqamqam	Jabal Sakamkam,Jabal Saqamqam	25.18982	56.31074	T	RDGE	AE		04				0		145	Asia/Dubai	2011-11-06
+290909	Saqamqam	Saqamqam	As Saqamqam,Sakamkam,Saqamqam	25.17467	56.33039	P	PPL	AE		04				0		160	Asia/Dubai	2011-11-06
+290910	Saqal	Saqal	Saqal	25.27976	56.1859	V	GRVP	AE		05				0		386	Asia/Dubai	2011-11-06
+290911	Dawḩat ÅžÄniyah	Dawhat Saniyah	Dawhat Saniyah,Dawḩat ÅžÄniyah	24.15343	51.77192	H	COVE	AE		01				0		1	Asia/Dubai	2011-11-06
+290912	Khabrat Sanad	Khabrat Sanad	Khabrat Sanad	24.08333	51.7	H	WLL	AE		01				0		7	Asia/Dubai	2011-11-06
+290913	Sanad	Sanad	Sanad	24.1	51.7	L	LCTY	AE		01				0		14	Asia/Dubai	2011-11-06
+290914	WÄdÄ« SanÄbil	Wadi Sanabil	Wadi Sanabil,WÄdÄ« SanÄbil	24.66808	55.55881	T	TRGD	AE		00				0		221	Asia/Dubai	2011-11-06
+290915	SamnÄn	Samnan	Samnan,SamnÄn	25.3	55.45	L	LCTY	AE		00				0		13	Asia/Dubai	2011-11-06
+290916	Å¢awÄ« SamḩÄn	Tawi Samhan	Tawi Samhan,Tawi Semhan,Tawi Simhan,Å¢awÄ« SamḩÄn	24.82866	55.44335	H	WLL	AE		03				0		122	Asia/Dubai	2011-11-06
+290917	Raml SamḩÄn	Raml Samhan	Raml Samhan,Raml SamḩÄn	24.83333	55.46667	T	SAND	AE		03				0		129	Asia/Dubai	2011-11-06
+290918	SamḩÄn	Samhan	Al Irma,Samhan,SamḩÄn,Semhan	24.83333	55.46667	T	HLL	AE	AE	03				0		129	Asia/Dubai	2011-11-06
+290919	Å¢awÄ« SamḩÄ’	Tawi Samha'	Tawi Samha',Å¢awÄ« SamḩÄ’	25.56444	55.82694	H	WLL	AE		07				0		46	Asia/Dubai	2011-11-06
+290920	Samarat	Samarat	Samarat	25.68907	56.13698	P	PPL	AE		01				0		1211	Asia/Dubai	2011-11-06
+290921	Sayh Samarah	Sayh Samarah	Sayh Samarah	24.21929	55.43518	T	TRGD	AE		01				0		205	Asia/Dubai	2011-11-06
+290922	WÄdÄ« SamÄḩ	Wadi Samah	Wadi Samah,WÄdÄ« SamÄḩ	25.44621	55.98338	H	WAD	AE		05				0		125	Asia/Dubai	2011-11-06
+290923	Jabal SamÄḩ	Jabal Samah	Jabal Samah,Jabal SamÄḩ	25.12605	56.17094	T	MT	AE		00				0		954	Asia/Dubai	2011-11-06
+290924	Jabal SamÄḩ	Jabal Samah	Jabal Samah,Jabal SamÄḩ	25.4165	55.96082	T	DUNE	AE		05				0		204	Asia/Dubai	2011-11-06
+290925	SamÄḩ	Samah	Samah,SamÄḩ	24.91667	56.3	L	TRB	AE		00				0		108	Asia/Dubai	2011-11-06
+290926	Salwá	Salwa	Salwa,Salwah,Salwá,Sawa,Sawá	25.02031	55.14772	L	LCTY	AE		03				0		20	Asia/Dubai	2011-11-06
+290927	Sayḩ Salmá	Sayh Salma	Sayh Salma,Sayḩ Salmá	24.16132	55.4748	T	TRGD	AE		01				0		237	Asia/Dubai	2011-11-06
+290928	Raml as Salmá	Raml as Salma	Raml as Salma,Raml as Salmá	24.16667	55.48333	T	DUNE	AE		01				0		243	Asia/Dubai	2011-11-06
+290929	Sayḩ as Salm	Sayh as Salm	Sayh as Salam,Sayh as Salm,Sayḩ as Salam,Sayḩ as Salm	24.83631	55.29693	T	TRGD	AE		03				0		88	Asia/Dubai	2011-11-06
+290930	Raml as Salm	Raml as Salm	Raml as Salam,Raml as Salm	24.85099	55.25704	T	DUNE	AE		03				0		55	Asia/Dubai	2011-11-06
+290931	WÄdÄ« Sallah	Wadi Sallah	Wadi Sallah,WÄdÄ« Sallah	24.56329	55.64776	T	TRGD	AE		01				0		279	Asia/Dubai	2011-11-06
+290932	Sayḩ Sallah	Sayh Sallah	Sayh Sallah,Sayḩ Sallah	23.93198	55.47704	T	TRGD	AE		01				0		186	Asia/Dubai	2011-11-06
+290933	Sallah	Sallah	Sallah	24.57314	55.61947	L	LCTY	AE		01				0		250	Asia/Dubai	2011-11-06
+290934	WÄdÄ« Sall	Wadi Sall	Wadi Sal,Wadi Sall,WÄdÄ« Sal,WÄdÄ« Sall	25.84083	56.06722	H	WAD	AE	AE	05				0		75	Asia/Dubai	2011-11-06
+290935	Jabal Sall	Jabal Sall	Jabal Sal,Jabal Sall	25.76028	56.08861	T	MT	AE	AE	05				0		799	Asia/Dubai	2011-11-06
+290936	Sall	Sall	Sal,Sall	25.74903	56.09217	V	CULT	AE		05				0		563	Asia/Dubai	2011-11-06
+290937	Falaj as Salj	Falaj as Salj	Falaj as Salj	25.44825	55.98449	H	STMI	AE		05				0		125	Asia/Dubai	2011-11-06
+290938	WÄdÄ« SalÄ«mah	Wadi Salimah	Wadi Salimah,Wadi Salum,WÄdÄ« SalÄ«mah,WÄdÄ« SalÅ«m	24.72335	55.66265	T	TRGD	AE		00				0		244	Asia/Dubai	2011-11-06
+290939	Shu‘bat Salīmah	Shu`bat Salimah	Shu`bat Salimah,Shu`bat Silima,Shu‘bat Salīmah,Shu‘bat Silima	24.0475	55.83278	H	WAD	AE		01				0		324	Asia/Dubai	2011-11-06
+290940	Baţn Salīmah	Batn Salimah	Batn Salima,Batn Salimah,Baţn Salima,Baţn Salīmah	24.91893	55.54126	T	DPR	AE		03				0		166	Asia/Dubai	2011-11-06
+290941	Salīmah	Salimah	Saleema,Salimah,Salīmah	22.9118	54.3397	T	DPR	AE		01				0		164	Asia/Dubai	2011-11-06
+290942	Ţawī Salīm	Tawi Salim	Tawi Salim,Ţawī Salīm	25.33896	55.82837	H	WLL	AE		07				0		79	Asia/Dubai	2011-11-06
+290943	Sayḩ SalÄ«l	Sayh Salil	Madiq al-Salil,Maá¸Ä«q al-SalÄ«l,Sayh Salil,Sayḩ SalÄ«l,Sih Salil	23.13333	55.41667	T	TRGD	AE		00				0		120	Asia/Dubai	2011-11-06
+290944	ÅžÄliḩīyah	Salihiyah	As Salihiyah,AÅŸ ÅžÄliḩīyah,Salihiyah,ÅžÄliḩīyah	25.72161	55.99081	P	PPL	AE		05				0		21	Asia/Dubai	2011-11-06
+290945	Saleh	Saleh	Saleh,Salih,ÅžÄliḩ	26.13333	55.75	L	OILF	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290946	Jabal SalḩÄl	Jabal Salhal	Jabal Salhal,Jabal SalḩÄl	25.25969	56.18567	T	MT	AE		05				0		634	Asia/Dubai	2011-11-06
+290947	Salbūk	Salbuk	Salbuk,Salbūk	23.87316	53.76852	T	DUNE	AE		01				0		55	Asia/Dubai	2011-11-06
+290948	SalÄn KhalfÄn	Salan Khalfan	Salan Khalfan,SalÄn KhalfÄn	23.93776	53.52864	T	DUNE	AE		01				0		43	Asia/Dubai	2011-11-06
+290949	Sabkhat as Salamīyah	Sabkhat as Salamiyah	As Salamiyah Sabkhat,Sabkhat as Salamiyah,Sabkhat as Salamīyah	23.99347	53.76611	H	SBKH	AE		01				0		12	Asia/Dubai	2011-11-06
+290950	SalÄm	Salam	Salam,SalÄm	25.66583	55.8525	H	WLL	AE		07				0		66	Asia/Dubai	2011-11-06
+290951	Sabkhat Salal	Sabkhat Salal	Sabkhat Salal,Sabkhat Salil,Sabkhat Salīl	23.74706	55.12282	H	SBKH	AE		01				0		103	Asia/Dubai	2011-11-06
+290952	Salala	Salala	As Salahah,AÅŸ ÅžalÄḩah,Salahah,Salala,ÅžalÄḩah	24.1955	53.53829	T	ISL	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290953	Bid‘ Salaal	Bid` Salaal	Bid` Salaal,Bid‘ Salaal	23.9	54.7	H	WLL	AE		01				0		90	Asia/Dubai	2011-11-06
+290954	Sala	Sala	Sala	24.16667	55.4	T	DUNE	AE		01				0		198	Asia/Dubai	2011-11-06
+290955	Jabal Sakhbīrī	Jabal Sakhbiri	Jabal Sakhbiri,Jabal Sakhbīrī	25.10639	56.03417	T	HLL	AE		05				0		366	Asia/Dubai	2011-11-06
+290956	SÄ’if	Sa'if	Sa'if,SÄ’if	25.1842	56.24205	P	PPL	AE		04				0		415	Asia/Dubai	2011-11-06
+290957	Å¢awÄ« Sa‘īdÄ«	Tawi Sa`idi	Tawi Sa`idi,Tawi Zaid,Tawi Zayd,Å¢awÄ« Sa‘īdÄ«,Å¢awÄ« Zayd,Å¢ÄwÄ« Zaid	25.54241	55.89153	H	WLL	AE		05				0		26	Asia/Dubai	2011-11-06
+290958	Å¢awÄ« Sa‘īd Bin HuwaydÄn	Tawi Sa`id Bin Huwaydan	Tawi Sa`id Bin Huwaydan,Å¢awÄ« Sa‘īd Bin HuwaydÄn	24.97961	55.78755	H	WLL	AE		06				0		172	Asia/Dubai	2011-11-06
+290959	Bid‘ Sa‘īd	Bid` Sa`id	Bada Sa`id,Bada Sa‘īd,Bid` Sa`id,Bid‘ Sa‘īd	23.65747	52.49121	H	WLL	AE		01				0		68	Asia/Dubai	2011-11-06
+290960	SÄ’ibah	Sa'ibah	Sa'iba,Sa'ibah,Sa’iba,SÄ’ibah	22.95698	54.27151	T	DPR	AE		01				0		98	Asia/Dubai	2011-11-06
+290961	GhaffÄt SaḩmÄ«	Ghaffat Sahmi	Ghaffat Sahmi,GhaffÄt SaḩmÄ«	24.5	55.26667	T	DUNE	AE		01				0		123	Asia/Dubai	2011-11-06
+290962	Sayḩ Sahmah	Sayh Sahmah	Sayh Sahmah,Sayḩ Sahmah	23.15	55.25	T	DPR	AE		00				0		104	Asia/Dubai	2011-11-06
+290963	Ḩaql Sahl	Haql Sahl	Haql Sahl,Sahal,Sahel,Sahil,Ḩaql Sahl	23.70594	54.32028	L	OILF	AE		01				0		114	Asia/Dubai	2011-11-06
+290964	WÄdÄ« Åžaḩanah	Wadi Sahanah	Wadi Sahanah,WÄdÄ« Åžaḩanah	25.28025	56.32255	H	WAD	AE		00				0		63	Asia/Dubai	2011-11-06
+290965	Saḩanah	Sahanah	Sahanah,Saḩanah	25.28556	56.3084	P	PPL	AE		06				0		99	Asia/Dubai	2011-11-06
+290966	SaḩÄb	Sahab	Sahab,SaḩÄb	25.15848	56.08929	L	LCTY	AE		05				0		286	Asia/Dubai	2011-11-06
+290967	Å¢awÄ« SÄji‘ah	Tawi Saji`ah	Tawi Saghyah,Tawi Saja'a,Tawi Saja`ah,Tawi Saji`ah,TÄwÄ« Saja’a,Å¢awÄ« Saghyah,Å¢awÄ« SÄja‘ah,Å¢awÄ« SÄji‘ah	25.30552	55.58034	H	WLL	AE		06				0		39	Asia/Dubai	2011-11-06
+290968	Saghyah	Saghyah	Saghyah,Sajaa	25.25	55.78333	L	GASF	AE	AE	06				0		113	Asia/Dubai	2011-11-06
+290969	Sagh‘ayn	Sagh`ayn	Sagh'ain,Sagh`ayn,Sagh‘ayn,Sagh’ain	24.53333	51.11667	H	WLL	AE		01				0		3	Asia/Dubai	2011-11-06
+290970	WÄdÄ« aÅŸ ÅžafÅŸaf	Wadi as Safsaf	Wadi as Safsaf,WÄdÄ« aÅŸ ÅžafÅŸaf	25.33999	56.02183	H	WAD	AE		00				0		201	Asia/Dubai	2011-11-06
+290971	Ţawī Şafşaf	Tawi Safsaf	Tawi Safsaf,Ţawī Şafşaf	25.32833	56.01056	H	WLL	AE		02				0		219	Asia/Dubai	2011-11-06
+290972	Jabal ÅžafÅŸaf	Jabal Safsaf	Jabal Safsaf,Jabal ÅžafÅŸaf	25.33111	56.02306	T	HLL	AE		02				0		198	Asia/Dubai	2011-11-06
+290973	WÄdÄ« Åžafad	Wadi Safad	Wadi Safad,WÄdÄ« Åžafad	25.22915	56.35145	H	WAD	AE		04				0		12	Asia/Dubai	2011-11-06
+290974	Jabal Åžafad	Jabal Safad	Jabal Safad,Jabal Åžafad	25.23315	56.28695	T	MT	AE		04				0		640	Asia/Dubai	2011-11-06
+290975	Åžafad	Safad	Safad,Sufad,Åžafad	25.22165	56.3239	P	PPL	AE		04				0		71	Asia/Dubai	2011-11-06
+290976	WÄdÄ« ÅžafÄ	Wadi Safa	Wadi Safa,WÄdÄ« ÅžafÄ	25.06554	55.26203	T	TRGD	AE		03				0		30	Asia/Dubai	2011-11-06
+290977	Ra’s aş Şadr	Ra's as Sadr	Ra's as Sadr,Ra’s aş Şadr	24.6753	54.65663	T	PT	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290978	Ra’s as Sa‘dÄ«yÄt	Ra's as Sa`diyat	Ra's as Sa`diyat,Ras al Sa`diya,Ras al Sa‘diya,Ra’s as Sa‘dÄ«yÄt	24.58542	54.47465	T	PT	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290979	Khawr as Sa‘dÄ«yÄt	Khawr as Sa`diyat	Khawr Essadiyat,Khawr EssÄdiyÄt,Khawr as Sa`diyat,Khawr as Sa‘dÄ«yÄt	24.62296	54.46416	H	CHNM	AE		01				0		-9999	Asia/Dubai	2011-11-06
+290980	Ţawī Sa‘dīyah	Tawi Sa`diyah	Tawi Sa`diyah,Ţawī Sa‘dīyah	24.87867	56.16899	H	WLL	AE		05				0		191	Asia/Dubai	2011-11-06
+290981	Sa‘dīyah	Sa`diyah	Sa`diyah,Sa‘dīyah	23.69426	54.10408	H	WLL	AE		01				0		97	Asia/Dubai	2011-11-06
+290982	Sa‘dÄ«yah	Sa`diyah	Sa`diyah,Sa‘dÄ«yah,Tawi Sa'adiya,TÄwÄ« Sa’adiya	25.1	55.7	V	TREE	AE		06				0		156	Asia/Dubai	2011-11-06
+290983	Å¢awÄ« as SÄdd	Tawi as Sadd	Sa`ad,Sa‘ad,Tawi Sa`d,Tawi as Sadd,Å¢awÄ« Sa‘d,Å¢awÄ« as SÄdd	24.20806	55.50417	H	WLLS	AE	AE	01				0		211	Asia/Dubai	2011-11-06
+290984	Raml as SÄdd	Raml as Sadd	Raml Sa`d,Raml Sa‘d,Raml as Sadd,Raml as SÄdd	24.2	55.48333	T	DUNE	AE	AE	01				0		213	Asia/Dubai	2011-11-06
+290985	Jabal Sa‘d	Jabal Sa`d	Jabal Sa`d,Jabal Sa‘d	25.11355	56.11717	T	MT	AE		05				0		427	Asia/Dubai	2011-11-06
+290986	Sa‘d	Sa`d	Sa`d,Sa‘d	25.26667	56.28333	P	PPL	AE		06				0		213	Asia/Dubai	2011-11-06
+290987	Ramlat Åžabr	Ramlat Sabr	Ramlat Sabar,Ramlat Sabr,Ramlat Åžabr	24.03866	55.4161	T	DUNE	AE		01				0		202	Asia/Dubai	2011-11-06
+290988	Sabkhah	Sabkhah	Sabakha,Sabkhah	23.3	53.85	P	PPL	AE	AE	01				0		136	Asia/Dubai	2011-11-06
+290989	Sabkhah	Sabkhah	Sabkha,Sabkhah,Sabukhah	23.12917	53.98181	P	PPL	AE		01				0		166	Asia/Dubai	2011-11-06
+290990	Sabkah	Sabkah	Sabka,Sabkah	25.29255	55.39472	H	WLL	AE		03				0		8	Asia/Dubai	2011-11-06
+290991	Ţawī Sabarad	Tawi Sabarad	Tawi Sabarad,Ţawī Sabarad	25.29389	55.89944	H	WLL	AE		06				0		144	Asia/Dubai	2011-11-06
+290992	Sabalah	Sabalah	Sabalah,Sablah	22.92596	53.45262	T	DPR	AE		01				0		61	Asia/Dubai	2011-11-06
+290993	SabÄ’is	Saba'is	Saba'is,SabÄ’is	24.83333	55.5	L	TRB	AE		03				0		169	Asia/Dubai	2011-11-06
+290994	Qarn Şa‘bah	Qarn Sa`bah	Qarn Sa`bah,Qarn Şa‘bah	24.46867	55.72733	T	HLL	AE		01				0		330	Asia/Dubai	2011-11-06
+290995	Sa‘abah	Sa`abah	Sa`abah,Sa`bah,Sa‘abah,Sa‘bah	24.99417	56.025	P	PPLQ	AE		05				0		306	Asia/Dubai	2011-11-06
+290996	NaqÄ Sa‘Ädah	Naqa Sa`adah	Naqa Sa`adah,NaqÄ Sa‘Ädah	23.42818	55.38215	T	DUNE	AE		01				0		195	Asia/Dubai	2011-11-06
+290997	Ţawī Ruwayyah	Tawi Ruwayyah	Tawi Mirdif,Tawi Ruwayyah,Ţawī Mirdif,Ţawī Ruwayyah	24.89283	55.66387	H	WLL	AE		03				0		209	Asia/Dubai	2011-11-06
+290998	Ruwayyah	Ruwayyah	Ruwayyah	24.8871	55.66016	L	LCTY	AE		03				0		205	Asia/Dubai	2011-11-06
+290999	Ra’s Ruwaysīyah	Ra's Ruwaysiyah	Ra's Harmiyah,Ra's Ru'aysiyah,Ra's Ruwaysiyah,Ra’s Harmīyah,Ra’s Ruwaysīyah,Ra’s Ru’aysīyah	24.12591	53.44243	T	PT	AE		01				0		-9999	Asia/Dubai	2011-11-06
+291000	Ruwaysīyah	Ruwaysiyah	Ru'aysiyah,Ruwaisiyya,Ruwaysiyah,Ruwaysīyah,Ruweisiya,Ru’aysīyah	24.11927	53.4354	L	LCTY	AE		01				0		1	Asia/Dubai	2011-11-06
+291001	Sayḩ Ruwayshid	Sayh Ruwayshid	Sayh Ruwayshid,Sayḩ Ruwayshid	25.3	55.66667	T	TRGD	AE		06				0		76	Asia/Dubai	2011-11-06
+291002	Khawr ar Ruways	Khawr ar Ruways	Khawr ar Ru'ays,Khawr ar Ruways,Khawr ar Ru’ays	24.13966	52.67385	H	INLT	AE		01				0		1	Asia/Dubai	2011-11-06
+291003	Ruwaymayah	Ruwaymayah	Ruwaymayah	24.80098	55.64042	L	LCTY	AE		03				0		230	Asia/Dubai	2011-11-06
+291004	Jabal Ruwayḑah	Jabal Ruwaydah	Jabal Ruwaydah,Jabal Ruwayḑah	25.50556	56.08844	T	MT	AE		04				0		493	Asia/Dubai	2011-11-06
+291005	Ruwayḑah	Ruwaydah	Riweidah,Riweiá¸ah,Ruwaidha,Ruwaydah,Ruwayḑah	23.1039	53.97789	L	OAS	AE		01				0		98	Asia/Dubai	2011-11-06
+291006	RuwÄlÄ	Ruwala	Ruwala,Ruwalla,RuwÄlÄ	23.2956	54.20134	H	SPNG	AE		01				0		158	Asia/Dubai	2011-11-06
+291007	Ruqayyib	Ruqayyib	Ruqayyib	23.93586	52.88188	H	WLL	AE		01				0		59	Asia/Dubai	2011-11-06
+291008	Ruqayyah	Ruqayyah	Ruqayyah	23.28333	54.65	H	WLL	AE		01				0		126	Asia/Dubai	2011-11-06
+291009	Ruqayyah	Ruqayyah	Ruqayyah	23.03532	53.60933	L	OAS	AE		01				0		159	Asia/Dubai	2011-11-06
+291010	Shaqqat ar Ruqayţuwah	Shaqqat ar Ruqaytuwah	Ruqaytuwwah,Ruqayţuwwah,Shaqqat ar Ruqaytuwah,Shaqqat ar Ruqaytuwwah,Shaqqat ar Ruqayţuwah,Shaqqat ar Ruqayţuwwah	23.38663	55.25216	T	TRGD	AE		01				0		121	Asia/Dubai	2011-11-06
+291011	Sabkhat ar Ruqayţuwah	Sabkhat ar Ruqaytuwah	Sabkhat Bu Satma,Sabkhat Bū Satma,Sabkhat ar Ruqaytuwah,Sabkhat ar Ruqaytuwwah,Sabkhat ar Ruqayţuwah,Sabkhat ar Ruqayţūwwah	23.44808	55.11346	H	SBKH	AE		01				0		110	Asia/Dubai	2011-11-06
+291012	‘Irq Ruqayţuwah	`Irq Ruqaytuwah	`Irq Ruqaytuwah,`Irq Ruqaytuwwah,‘Irq Ruqayţuwah,‘Irq Ruqayţuwwah	23.38449	55.20788	T	DUNE	AE		01				0		187	Asia/Dubai	2011-11-06
+291013	Ţawī Ruqayshah	Tawi Ruqayshah	Tawi Ruqayshah,Ţawī Ruqayshah	24.98485	55.78776	H	WLL	AE		06				0		163	Asia/Dubai	2011-11-06
+291014	Ruq‘at Ya‘Äribah	Ruq`at Ya`aribah	Raq`al al Jarba,Raq‘al al Jarba,Ruq`at Ya`aribah,Ruq‘at Ya‘Äribah	23.89652	55.48556	T	TRGD	AE		01				0		145	Asia/Dubai	2011-11-06
+291015	Ruq‘at Tulūl	Ruq`at Tulul	Ruq`at Tulul,Ruq‘at Tulūl	22.95827	55.20907	T	DPR	AE		01				0		126	Asia/Dubai	2011-11-06
+291016	Ruq‘at Sunayyim	Ruq`at Sunayyim	Ruq`at Sunayyim,Ruq‘at Sunayyim	23.65155	55.29791	T	TRGD	AE		01				0		114	Asia/Dubai	2011-11-06
+291017	Ruq‘at Ruqayţuwah	Ruq`at Ruqaytuwah	Ruq`at Ruqatuwwah,Ruq`at Ruqaytuwah,Ruq`at Ruqaytuwwah,Ruq‘at Ruqayţuwah,Ruq‘at Ruqayţuwwah,Ruq‘at Ruqaţuwwah	23.40594	55.28253	T	DPR	AE		01				0		121	Asia/Dubai	2011-11-06
+291018	Ruq‘at Nuşb	Ruq`at Nusb	Ruq`at Nusb,Ruq`at Nusub,Ruq‘at Nuşb,Ruq‘at Nuşub	24.05	55.41667	T	SAND	AE		01				0		173	Asia/Dubai	2011-11-06
+291019	Ruq‘at Muşallī	Ruq`at Musalli	Ruq`at Musalli,Ruq‘at Muşallī	24.85889	55.57612	T	DUNE	AE		03				0		195	Asia/Dubai	2011-11-06
+291020	Ruq‘at Musajira	Ruq`at Musajira	Ruq`at Musajira,Ruq‘at Musajira	24.84075	55.65624	T	DUNE	AE		03				0		228	Asia/Dubai	2011-11-06
+291021	Muḩayşinah	Muhaysinah	Muhaysinah,Muḩayşinah,Ruq`ah Muhassanah,Ruq`at Muhassanah,Ruq‘ah Muḩaşşanah,Ruq‘at Muḩaşşanah	25.25528	55.39278	L	LCTY	AE	AE	03				0		15	Asia/Dubai	2011-11-06
+291022	Ruq‘at Maghis	Ruq`at Maghis	Ruq`at Maghis,Ruq‘at Maghis	23.61802	55.4466	T	TRGD	AE		01				0		139	Asia/Dubai	2011-11-06
+291023	Ruq‘at Ḩumaydī	Ruq`at Humaydi	Hameidha,Humaydah,Ruq`at Humaydi,Ruq‘at Ḩumaydī,Ḩumayḑah	24.79964	55.70185	T	DUNE	AE		03				0		260	Asia/Dubai	2011-11-06
+291024	Ruq‘at Ḩulayw	Ruq`at Hulayw	Ruq`at Hulayw,Ruq‘at Ḩulayw	23.63585	55.36908	T	TRGD	AE		01				0		157	Asia/Dubai	2011-11-06
+291025	Rafadah	Rafadah	Rafadah,Ruq`at Bu Zafidah,Ruq‘at Bū Z̧afīdah	24.86014	55.65022	T	DUNE	AE		03				0		217	Asia/Dubai	2011-11-06
+291026	Ruq‘at al Mīr	Ruq`at al Mir	Ruq`at al Mir,Ruq‘at al Mīr	22.98574	55.19227	H	SBKH	AE		01				0		100	Asia/Dubai	2011-11-06
+291027	Ruq‘at al ḨÄdh	Ruq`at al Hadh	Ruq`at al Hadh,Ruq‘at al ḨÄdh	22.94468	55.1886	H	SBKH	AE		01				0		105	Asia/Dubai	2011-11-06
+291028	Ruq‘at al ‘ArÄd	Ruq`at al `Arad	Raq`at al-`Arad,Raq‘at al-‘ArÄd,Ruq`at al Ard,Ruq`at al `Arad,Ruq‘at al Ard,Ruq‘at al ‘ArÄd	23.86265	55.50198	T	TRGD	AE		01				0		191	Asia/Dubai	2011-11-06
+291029	WÄdÄ« Rumḩ	Wadi Rumh	Wadi Rumh,WÄdÄ« Rumḩ	25.04006	56.32907	H	WAD	AE		06				0		24	Asia/Dubai	2011-11-06
+291030	Ţawī Rumḩ	Tawi Rumh	Tawi Rumh,Ţawī Rumḩ	25.01667	56.35	H	WLL	AE		06				0		7	Asia/Dubai	2011-11-06
+291031	Jabal Rumḩ	Jabal Rumh	Jabal Rumh,Jabal Rumḩ	25.02953	56.2807	T	MT	AE		04				0		369	Asia/Dubai	2011-11-06
+291032	Rumaylī	Rumayli	Rumayli,Rumaylī	26.02472	56.11083	V	CULT	AE		05				0		565	Asia/Dubai	2011-11-06
+291033	Jabal ar Rumaylah	Jabal ar Rumaylah	Jabal ar Rumaylah	25.43333	56.35	T	HLL	AE		04				0		34	Asia/Dubai	2011-11-06
+291034	Jabal Umayliḩ	Jabal Umaylih	Jabal Rumaylah,Jabal Umaylah,Jabal Umaylih,Jabal Umayliḩ	25.0503	55.82244	T	HLL	AE		06				0		253	Asia/Dubai	2011-11-06
+291035	RÅ«l á¸adnÄ	Rul Dadna	Rol Dadnah,Rol Ḍadnah,Rul Dadna,Rul Dadnah,Rul Dhadna,RÅ«l á¸adnah,RÅ«l á¸adnÄ	25.55481	56.34546	P	PPL	AE		04				0		26	Asia/Dubai	2011-11-06
+291036	Ţawī ar Rūl	Tawi ar Rul	Tawi ar Rul,Ţawī ar Rūl	25.57602	56.35214	H	WLLQ	AE		04				0		-9999	Asia/Dubai	2011-11-06
+291037	RukbÄt	Rukbat	Rukbat,RukbÄt	24.74428	54.65006	T	SPIT	AE		01				0		7	Asia/Dubai	2011-11-06
+291038	Ramlat ar Ruhayl	Ramlat ar Ruhayl	Ramlat ar Ruhayl	23.55	55.46667	T	DUNE	AE		00				0		188	Asia/Dubai	2011-11-06
+291039	Jabal Ruḩam	Jabal Ruham	Jabal Ruham,Jabal Ruḩam	25.13333	56.26667	T	HLL	AE		04				0		93	Asia/Dubai	2011-11-06
+291040	RughaylÄt	Rughaylat	Righeilat,RigheilÄt,Rughaylat,RughaylÄt,Rugheilat	25.10552	56.3563	P	PPL	AE		04				0		23	Asia/Dubai	2011-11-06
+291041	‘Ayn ar Rufayşah	`Ayn ar Rufaysah	`Ayn ar Rufaysah,‘Ayn ar Rufayşah	25.35	56.31667	H	SPNG	AE		06				0		77	Asia/Dubai	2011-11-06
+291042	RufayÅŸah	Rufaysah	Rufaysah,RufayÅŸah	25.16778	56.17722	V	CULT	AE		01				0		389	Asia/Dubai	2011-11-06
+291043	Bandar Rudaym	Bandar Rudaym	Bandar Rudaym	24.06323	53.69867	H	COVE	AE		01				0		-9999	Asia/Dubai	2011-11-06
+291044	Å¢awÄ« Rubayyah	Tawi Rubayyah	Tawi Rabaiya,Tawi Rubayyah,TÄwÄ« Rabaiya,Å¢awÄ« Rubayyah	25.73333	56.05	H	WLL	AE	AE	05				0		361	Asia/Dubai	2011-11-06
+291045	Rubay‘ah	Rubay`ah	Rubay`ah,Rubay‘ah	24.25	55.08333	T	DPR	AE		01				0		123	Asia/Dubai	2011-11-06
+291046	WÄdÄ« RiyÄmah	Wadi Riyamah	Wadi Riyama,Wadi Riyamah,WÄdÄ« RiyÄmah	25.55023	56.04815	H	WAD	AE		04				0		237	Asia/Dubai	2011-11-06
+291047	RiyÄmah	Riyamah	Riyama,Riyamah,RiyÄmah	25.54564	56.05836	P	PPL	AE		04				0		179	Asia/Dubai	2011-11-06
+291048	Jabal RiyÄdir	Jabal Riyadir	Jabal Riyadir,Jabal RiyÄdir	25.3	56.33333	T	MT	AE		06				0		42	Asia/Dubai	2011-11-06
+291049	Å¢awÄ« RiqÄnah	Tawi Riqanah	Riqana,Tawi Riqanah,Å¢awÄ« RiqÄnah	24.3418	55.69959	H	WLL	AE		01				0		310	Asia/Dubai	2011-11-06
+291050	‘Uqlat ar Rimth	`Uqlat ar Rimth	`Uqlat ar Rimth,‘Uqlat ar Rimth	24.43333	51.11667	H	WLL	AE		01				0		6	Asia/Dubai	2011-11-06
+291051	RimÄḩ	Rimah	Al Ramah,Rimah,RimÄḩ	24.79667	55.61194	V	TREE	AE	AE	03				0		224	Asia/Dubai	2011-11-06
+291052	Rimá	Rima	Rima,Rimá	25.16784	56.11795	P	PPL	AE		05				0		519	Asia/Dubai	2011-11-06
+291053	RiḩyÄt	Rihyat	Rihyat,RiḩyÄt	24.88151	55.44885	T	SAND	AE		03				0		152	Asia/Dubai	2011-11-06
+291054	Ţawī Rifđ	Tawi Rifa`	Tawi Rifa`,Ţawī Rifđ	24.96961	55.78658	H	WLL	AE		06				0		173	Asia/Dubai	2011-11-06
+291055	GhalÄ«lat RÄziqÄ«	Ghalilat Raziqi	Ghalilat Raziqi,GhalÄ«lat RÄziqÄ«	25.6	56.28333	H	WADM	AE		04				0		95	Asia/Dubai	2011-11-06
+291056	WÄdÄ« Rayj	Wadi Rayj	Wadi Rayj,WÄdÄ« Rayj	25.0183	55.2567	T	TRGD	AE		03				0		37	Asia/Dubai	2011-11-06
+291057	WÄdÄ« RaybÄ«yah	Wadi Raybiyah	Wadi Raibiya,Wadi Raybiyah,WÄdÄ« Raibiya,WÄdÄ« RaybÄ«yah	25.73472	56.02722	H	WAD	AE	AE	05				0		9	Asia/Dubai	2011-11-06
+291058	Rawḑah	Rawdah	Rawdah,Rawḑah	24.09028	55.56194	T	DPR	AE		01				0		215	Asia/Dubai	2011-11-06
+291059	Ra’s SiyÄd	Ra's Siyad	Ra's Seyad,Ra's Siyad,Ra’s SeyÄd,Ra’s SiyÄd	24.55	51.65	T	ISL	AE		01				0		-9999	Asia/Dubai	2011-11-06
+291060	Ra’s Qal‘ah	Ra's Qal`ah	Ra's Qal`ah,Ra’s Qal‘ah	24.19222	55.58333	T	DUNE	AE		01				0		235	Asia/Dubai	2011-11-06
+291061	Ar RÄshidÄ«yah	Ar Rashidiyah	Ar Rashidiyah,Ar RÄshidÄ«yah,Rashdia,Rashidiyah,RashÄ«dÄ«yah	25.22365	55.38894	P	PPLX	AE		03				0		20	Asia/Dubai	2011-11-06
+291062	Å¢awÄ« RÄshid Bin Sa‘īd	Tawi Rashid Bin Sa`id	Tawi Rashid Bin Sa`id,Å¢awÄ« RÄshid Bin Sa‘īd	25.65528	55.95861	H	WLL	AE		05				0		22	Asia/Dubai	2011-11-06
+291063	Å¢awÄ« RÄshid Bin Ḩamad	Tawi Rashid Bin Hamad	Tawi Rashid Bin Hamad,Å¢awÄ« RÄshid Bin Ḩamad	25.24	55.91278	H	WLL	AE		06				0		136	Asia/Dubai	2011-11-06
+291064	RÄshid al GharbÄ«	Rashid al Gharbi	Rashid al Gharbi,RÄshid al GharbÄ«,Tawi Rashid Gharbiyah,Tawi Rashid al Gharbiyah,Å¢awÄ« RÄshid GharbÄ«yah,Å¢awÄ« RÄshid al GharbÄ«yah	25.35833	55.70528	H	WLL	AE	AE	06				0		74	Asia/Dubai	2011-11-06
+291065	Å¢awÄ« RÄshidah	Tawi Rashidah	Tawi Rashidah,Å¢awÄ« RÄshidah	25.16667	55.96667	H	WLL	AE		05				0		234	Asia/Dubai	2011-11-06
+291066	Å¢awÄ« RÄshid	Tawi Rashid	Tawi Rashid,Å¢awÄ« RÄshid	25.33333	55.78333	H	WLL	AE		06				0		105	Asia/Dubai	2011-11-06
+291067	Nadd RÄshid	Nadd Rashid	Nadd Rashid,Nadd RÄshid	25.21944	55.40556	T	DUNE	AE		03				0		24	Asia/Dubai	2011-11-06
+291068	MÄ«nÄ’ RÄshid	Mina' Rashid	Mina' Rashid,MÄ«nÄ’ RÄshid,Port Rashid,Rachid Port	25.27056	55.29083	L	PRT	AE		03				0		-9999	Asia/Dubai	2011-11-06
+291069	Ḩaql RÄshid	Haql Rashid	Haql Rashid,Rashid Oilfield,Ḩaql RÄshid	25.23333	55.2	L	OILF	AE	AE	03				0		-9999	Asia/Dubai	2011-11-06
+291070	Barqat RashÄ«d	Barqat Rashid	Bada` Rashid,Bada‘ Rashid,Barqat Rashid,Barqat RashÄ«d,Barqat RÄshid	24.00562	54.01885	T	HLL	AE		01				0		18	Asia/Dubai	2011-11-06
+291071	Raseen	Raseen	Raseen	23.68333	54.78333	H	WLL	AE		01				0		130	Asia/Dubai	2011-11-06
+291072	Rasan	Rasan	Rasan	24.15	55.21667	T	DUNE	AE		01				0		151	Asia/Dubai	2011-11-06
+291073	Khawr Ra’s al Khaymah	Khawr Ra's al Khaymah	Khawr Khaymah,Khawr Ra's al Khaymah,Khawr Ra’s al Khaymah	25.78333	55.95	H	LGN	AE		05				0		-9999	Asia/Dubai	2011-11-06
+291074	Ra’s al Khaymah	Ra's al Khaymah	Julfa,Khaimah,Ra's al Khaymah,Ras al Khaima,Ras al Khaimah,Ra’s al Khaymah,RÄs al Khaima,ras alkhymt,رأس الخيمة	25.78953	55.9432	P	PPLA	AE		05				115949		27	Asia/Dubai	2011-11-06
+291075	Ra’s al Khaymah	Ra's al Khaymah	Jasimi Shaikhdom of Ras al-Khaimah,Ra's al Khaymah,Ran al Khaima,Ras al Khaima,Ras el Khaimah,Ras el Khaïmah,Raʼs al Khaymah,Ra’s al Khaymah,Sheikhdom of Ras al Khaimah,State of Ras Al Khaima,ras alkhymt,رأس الخيمة	25.66667	56	A	ADM1	AE		05				187535		12	Asia/Dubai	2011-11-05
+291076	WÄdÄ« Ra’s	Wadi Ra's	Wadi Ra's,WÄdÄ« Ra’s	25.10156	56.35801	H	WAD	AE		04				0		23	Asia/Dubai	2011-11-06
+291077	Jabal Ra’s	Jabal Ra's	Jabal Ra's,Jabal Ra’s	25.32634	56.3712	T	MT	AE		00				0		331	Asia/Dubai	2011-11-06
+291078	Sayḩ ar Raqq	Sayh ar Raqq	Sayh ar Raq,Sayh ar Raqq,Sayḩ ar Raq,Sayḩ ar Raqq	24.06667	55.83333	T	TRGD	AE	AE	01				0		316	Asia/Dubai	2011-11-06
+291079	Jabal Rams	Jabal Rams	Jabal Rams	25.86917	56.06917	T	MT	AE		05				0		774	Asia/Dubai	2011-11-06
+291080	RamrÄmÄ«yÄt	Ramramiyat	Birkat al Ju,Ramramiyah,Ramramiyat,Ramrammiyat,RamrammiyÄt,RamramÄ«yah,RamrÄmÄ«yÄt	23.98231	53.7953	T	HLL	AE		01				0	68	69	Asia/Dubai	2011-11-06
+291081	Ḩabl RamrÄm	Habl Ramram	Habl Ramram,Ḩabl RamrÄm	24.9	55.3	T	SAND	AE		03				0		62	Asia/Dubai	2011-11-06
+291082	Ḩabl RamrÄm	Habl Ramram	Habl Ramram,Ḩabl RamrÄm	24.91667	55.3	T	DUNE	AE		03				0		74	Asia/Dubai	2011-11-06
+291083	Za‘bīl	Za`bil	Raml Sabil,Raml Za`bil,Raml Za‘bīl,Za`bil,Za‘bīl	25.20408	55.2875	P	PPLX	AE		03				0		6	Asia/Dubai	2011-11-06
+291084	Ramlat ZarÄrah	Ramlat Zararah	Ramlat Zarara,Ramlat Zararah,Ramlat ZarÄrah	22.90077	54.49992	L	AREA	AE		01				0		131	Asia/Dubai	2011-11-06
+291085	Ramlah	Ramlah	Ramla,Ramlah,RamlÄ	25.35979	56.04452	P	PPL	AE		04				0		264	Asia/Dubai	2011-11-06
+291086	JazÄ«rat RamḩÄn	Jazirat Ramhan	Jazirat Ramhan,JazÄ«rat RamḩÄn,Ramhan,RamḩÄn,jzyrt rmhan,جزيرة رمحان	24.53778	54.52419	T	ISL	AE		01				0		10	Asia/Dubai	2011-11-06
+291087	Å¢awÄ« RamÄrÄ«m	Tawi Ramarim	Tawi Ramarim,Tawi Rimarim,Tawi Rumayram,TÄwÄ« Rimarim,Å¢awÄ« RamÄrÄ«m,Å¢awÄ« Rumayram	25.36083	55.535	H	WLL	AE		02				0		12	Asia/Dubai	2011-11-06
+291088	Ramaq	Ramaq	Ramaq	24.93333	55.13333	T	SAND	AE		03				0		42	Asia/Dubai	2011-11-06
+291089	QÅ«r ar RÄkibÄ«	Qur ar Rakibi	Qur ar Rakibi,QÅ«r ar RÄkibÄ«	25.5841	56.32873	T	MT	AE		04				0		357	Asia/Dubai	2011-11-06
+291090	NaqÄ RÄkah	Naqa Rakah	Naqa Rakah,NaqÄ RÄkah	23.95296	55.43484	T	DUNE	AE		01				0		232	Asia/Dubai	2011-11-06
+291091	GhÄf Rakaḑ	Ghaf Rakad	Ghaf Rakad,GhÄf Rakaḑ	24.51667	55.41667	T	HLL	AE		01				0		179	Asia/Dubai	2011-11-06
+291092	Sayḩ ar Rajībah	Sayh ar Rajibah	Sayh ar Rajibah,Sayḩ ar Rajībah	24.8	55.26667	T	TRGD	AE		03				0		71	Asia/Dubai	2011-11-06
+291093	Ḩadabat ar Rajībah	Hadabat ar Rajibah	Hadabat ar Rajibah,Ḩadabat ar Rajībah	24.8042	55.2656	T	HLL	AE		03				0		67	Asia/Dubai	2011-11-06
+291094	Raighnaan	Raighnaan	Raighnaan	23.16667	54.83333	H	WLL	AE		01				0		114	Asia/Dubai	2011-11-06
+291095	Raighan	Raighan	Raighan	23.26667	54.73333	H	WLL	AE		01				0		129	Asia/Dubai	2011-11-06
+291096	Raigha	Raigha	Raigha	24.44577	55.15561	T	SAND	AE		01				0		128	Asia/Dubai	2011-11-06
+291097	Raḩmah	Rahmah	Rahmah,Raḩmah	25.68	55.86361	H	WLL	AE		07				0		61	Asia/Dubai	2011-11-06
+291098	Rahfīyah	Rahfiyah	Rahfiya,Rahfiyah,Rahfīyah	22.79933	54.90797	T	DPR	AE		01				0		173	Asia/Dubai	2011-11-06
+291099	Jabal ar Raḩraḩ	Jabal ar Rahrah	Jabal Rahah,Jabal RÄḩah,Jabal ar Rahrah,Jabal ar Raḩraḩ	25.94833	56.14194	T	MT	AE	AE	05				0		1586	Asia/Dubai	2011-11-06
+291100	WÄdÄ« Raḩbah	Wadi Rahbah	Wadi Rahabah,Wadi Rahbah,WÄdÄ« Raḩabah,WÄdÄ« Raḩbah	25.92472	56.07167	H	WAD	AE	AE	05				0		12	Asia/Dubai	2011-11-06
+291101	Jabal Raḩabah	Jabal Rahabah	Jabal Rahabah,Jabal Raḩabah,Jabal ar Ra`aylah,Jabal ar Ra‘aylah	25.92583	56.11667	T	MT	AE	AE	05				0		1539	Asia/Dubai	2011-11-06
+291102	Raḩabah	Rahabah	Rahabah,Raḩabah	25.98333	56.08333	L	TRB	AE		05				0		37	Asia/Dubai	2011-11-06
+291103	Raḩá	Raha	Raha,Raḩá	24.87639	56.2175	V	CULT	AE		05				0		140	Asia/Dubai	2011-11-06
+291105	NaqÄ Raghwah	Naqa Raghwah	Naqa Raghawa,Naqa Raghwah,NaqÄ Raghawa,NaqÄ Raghwah	24.44834	55.23357	T	DUNE	AE		01				0		141	Asia/Dubai	2011-11-06
+291106	Å¢awÄ« Rafī‘ah	Tawi Rafi`ah	Tawi Rafi`ah,Tawi Rafiya,Tawi Rayifah,TÄwÄ« Rafiya,TÄwÄ« Rayifah,Å¢awÄ« Rafī‘ah	25.31972	55.73583	H	WLL	AE		06				0		79	Asia/Dubai	2011-11-06
+291107	Rafaq	Rafaq	Rafaq	24.87471	56.24559	P	PPL	AE		05				0		321	Asia/Dubai	2011-11-06
+291108	Å¢awÄ« RafÄh	Tawi Rafah	Tawi Rafah,Å¢awÄ« RafÄh	25.28333	55.88333	H	WLL	AE		06				0		110	Asia/Dubai	2011-11-06
+291109	Å¢awÄ« RafÄdah	Tawi Rafadah	Tawi Rafaada,Tawi Rafadah,Å¢awÄ« Rafaada,Å¢awÄ« RafÄdah	24.89462	55.74432	H	WLL	AE		06				0		185	Asia/Dubai	2011-11-06
+291110	Rafđ	Rafa`	Rafa`,Rafđ	25.34701	56.35014	P	PPL	AE		06				0		40	Asia/Dubai	2011-11-06
+291111	Radūm	Radum	Radum,Radūm	23.09185	53.61473	L	OAS	AE		01				0		172	Asia/Dubai	2011-11-06
+291112	RadÄt Ramz	Radat Ramz	Radat Ramz,Radath Ramz,RadÄt Ramz	25.5	56.1	H	WLL	AE	AE	05				0		218	Asia/Dubai	2011-11-06
+291113	Jabal ar Rabbah	Jabal ar Rabbah	Jabal ar Rabbah	25.39071	56.06641	T	HLL	AE		05				0		322	Asia/Dubai	2011-11-06
+291114	Sayḩ Rab‘	Sayh Rab`	Sayh Rab`,Sayḩ Rab‘	24.61506	54.86516	T	TRGD	AE		01				0		48	Asia/Dubai	2011-11-06
+291115	Quwayd	Quwayd	Quwayd	25.13333	56.05	L	TRB	AE		05				0		488	Asia/Dubai	2011-11-06
+291116	Quţūf	Qutuf	Qatuf,Qaṭūf,Qutuf,Quţūf	23.10971	53.72738	P	PPL	AE		01				0		87	Asia/Dubai	2011-11-06
+291117	Quţūf	Qutuf	Qutuf,Quţūf	23.10794	53.69333	T	DPR	AE		01				0		80	Asia/Dubai	2011-11-06
+291118	Jabal Qutayyib	Jabal Qutayyib	Jabal Qutayyib	25.94139	56.09333	T	HLL	AE		05				0		881	Asia/Dubai	2011-11-06
+291119	Jabal al Qusīy	Jabal al Qusiy	Jabal al Qusiy,Jabal al Qusīy	25.06667	56.31667	T	HLL	AE		06				0		90	Asia/Dubai	2011-11-06
+291120	QushÄsh	Qushash	Qushash,QushÄsh	23.95539	53.62028	T	SAND	AE		01				0		14	Asia/Dubai	2011-11-06
+291121	Sabkhat Qusaywirah	Sabkhat Qusaywirah	Sabkhat Qusaywirah	22.77956	55.04968	H	SBKH	AE		01				0		76	Asia/Dubai	2011-11-06
+291122	Qusaywirah	Qusaywirah	Geseiwra,Jiseiwrah,Qusaywirah	22.81918	54.79949	L	LCTY	AE		01				0		117	Asia/Dubai	2011-11-06
+291124	QuÅŸaydÄt	Qusaydat	Qusaidat,Qusaydat,QuÅŸaydÄt	25.77461	55.97002	P	PPLX	AE		05				0		21	Asia/Dubai	2011-11-06
+291125	Qurmidah	Qurmidah	Garmada,GarmadÄ,Jarmada,JarmadÄ,Qarmadah,Qurmidah	23.11957	53.82855	P	PPL	AE		01				0		154	Asia/Dubai	2011-11-06
+291126	Qurmidah	Qurmidah	Qarmadah,Qurmidah	23.11234	53.82152	L	OAS	AE		01				0		86	Asia/Dubai	2011-11-06
+291127	Jazīrat Qurmah	Jazirat Qurmah	Jazirat Qurmah,Jazīrat Qurmah	25.76667	55.95	T	ISL	AE		05				0		20	Asia/Dubai	2011-11-06
+291128	Khawr Qurm	Khawr Qurm	Khawr Qurm	25.72056	55.84667	H	LGN	AE		05				0		-9999	Asia/Dubai	2011-11-06
+291129	Qurm	Qurm	Qurm	25.91139	56.06417	P	PPL	AE		05				0		29	Asia/Dubai	2011-11-06
+291130	WÄdÄ« Qurayyah	Wadi Qurayyah	Wadi Qaraiyat,Wadi Qurayyah,WÄdÄ« Qurayyah	25.24214	56.34825	H	WAD	AE		04				0		16	Asia/Dubai	2011-11-06
+291131	Jabal Qurayyah	Jabal Qurayyah	Jabal Qurayyah	25.25531	56.3374	T	HLL	AE		04				0		40	Asia/Dubai	2011-11-06
+291132	Quraytisah	Quraytisah	Quraytisah	23.57867	54.87448	H	WLL	AE		01				0		147	Asia/Dubai	2011-11-06
+291133	Ţawī Qurayn	Tawi Qurayn	Tawi Qurayn,Ţawī Qurayn	23.66667	54.7	H	WLL	AE		01				0		143	Asia/Dubai	2011-11-06
+291134	Sayḩ Qurayḩah	Sayh Qurayhah	Sayh Qurayhah,Sayḩ Qurayḩah	25.41667	55.7	T	TRGD	AE		07				0		77	Asia/Dubai	2011-11-06
+291135	Quraydah	Quraydah	Quraydah	23.13464	53.86398	L	OAS	AE		01				0		167	Asia/Dubai	2011-11-06
+291136	QÅ«r	Qur	Al Qawr,Al Qor,Quor,Qur,QÅ«r	24.91214	56.09566	P	PPL	AE		05				0		340	Asia/Dubai	2011-11-06
+291137	Qunayy	Qunayy	Qunayy	23.16667	54.38333	H	WLL	AE		01				0		151	Asia/Dubai	2011-11-06
+291138	Bid‘ al QumzÄn	Bid` al Qumzan	Bid` al Qumzan,Bid‘ al QumzÄn	23.78619	53.42782	H	WLL	AE		01				0		102	Asia/Dubai	2011-11-06
+291139	Qulaydah	Qulaydah	Qulaydah	25.1968	55.96372	T	RDGE	AE		06				0		213	Asia/Dubai	2011-11-06
+291140	Qufayyid	Qufayyid	Qiff Rajajil,Qiff RajÄjÄ«l,Qufayyid	23.7573	52.87017	T	SAND	AE		01				0		94	Asia/Dubai	2011-11-06
+291141	Sih al Qubua	Sih al Qubua	Sayh al Qubua,Sayḩ al Qubua,Sih al Qubua	24.31519	54.88739	T	DPR	AE		01				0		75	Asia/Dubai	2011-11-06
+291142	Qubbat BÅ« Lisail	Qubbat Bu Lisail	Qubbat Bu Lisail,Qubbat BÅ« Lisail	24.36204	55.64738	L	LCTY	AE		01				0		278	Asia/Dubai	2011-11-06
+291143	WÄdÄ« Qubbah	Wadi Qubbah	Wadi Qubbah,WÄdÄ« Qubbah	25.3444	56.13202	H	WAD	AE		00				0		760	Asia/Dubai	2011-11-06
+291144	Sayḩ QubaysÄt	Sayh Qubaysat	Sayh Qubaysat,Sayḩ QubaysÄt	24.31489	55.05401	T	TRGD	AE		01				0		95	Asia/Dubai	2011-11-06
+291145	GhaḑÄ’ QÅ«bah	Ghada' Qubah	Ghada' Qubah,GhaḑÄ’ QÅ«bah,Sayh as Salab,Sayḩ as Salab	24.26986	55.30432	T	TRGD	AE		01				0		141	Asia/Dubai	2011-11-06
+291146	Qu‘aysah	Qu`aysah	Ge'aisa,Ge’aisa,Je`eisah,Je‘eiṣah,Qu`aysah,Qu‘aysah	22.9941	54.22184	P	PPL	AE		01				0		151	Asia/Dubai	2011-11-06
+291147	Quar Ah Qahlish	Quar Ah Qahlish	Quar Ah Qahlish	25.985	56.08639	P	PPL	AE		05				0		10	Asia/Dubai	2011-11-06
+291148	Jabal Qitab	Jabal Qitab	Jabal Kitas,Jabal Qitab	25.02017	56.2411	T	MT	AE		00				0	1029	1004	Asia/Dubai	2011-11-06
+291149	Khawr QirqishÄn	Khawr Qirqishan	Khawr Qirqishan,Khawr QirqishÄn	24.37884	54.36899	H	BAY	AE		01				0		-9999	Asia/Dubai	2011-11-06
+291150	WÄdÄ« Qimah	Wadi Qimah	Wadi Qamh,Wadi Qima,Wadi Qimah,Wadi Qimh,WÄdÄ« Qamḩ,WÄdÄ« Qimah,WÄdÄ« Qimh,WÄdÄ« QÄ«má	24.79862	56.13736	H	WAD	AE		03				0		306	Asia/Dubai	2011-11-06
+291151	Jabal Qimah	Jabal Qimah	Jabal Qima,Jabal Qimah,Jabal Qīmá	24.79495	56.15749	T	HLL	AE		03				0		609	Asia/Dubai	2011-11-06
+291152	Qimah	Qimah	Qamh,Qamḩ,Qima,Qimah,Qimh,Qīmá	24.78668	56.14143	P	PPL	AE		03				0		322	Asia/Dubai	2011-11-06
+291153	Ra’s al QilÄ‘	Ra's al Qila`	Qala`,Qala‘,Ra's al Qila`,Ras Djaliya,Ras Ijla,Ras Jaliya,Ras Jaliyah,Ras al Jala'a,Ras al Jala’a,Ras al-Qela',Ra’s al QilÄ‘,RÄs al-QelÄ’	24.15507	52.97896	T	PT	AE		01				0		-9999	Asia/Dubai	2011-11-06
+291154	Jabal Qidfa‘	Jabal Qidfa`	Jabal Qidfa`,Jabal Qidfa‘	25.33201	56.32246	T	MT	AE		06				0		473	Asia/Dubai	2011-11-06
+291155	Qidfa‘	Qidfa`	Qidfa,Qidfa`,Qidfa‘,Qidfi`,Qidfi‘	25.30426	56.37034	P	PPL	AE		06				0		45	Asia/Dubai	2011-11-06
+291156	Qayyat al Bawl	Qayyat al Bawl	Qayyat al Bawl	24.27465	54.62206	T	DUNE	AE		01				0		15	Asia/Dubai	2011-11-06
+291157	NaqÄ Qaydah	Naqa Qaydah	Naqa Qaydah,NaqÄ Qaydah	23.36667	55.4	T	DUNE	AE		00				0		174	Asia/Dubai	2011-11-06
+291158	Qawm ‘AnÄ«yÄt	Qawm `Aniyat	Qaum `Aniyat,Qaum ‘AnÄ«yÄt,Qawm `Aniyat,Qawm ‘AnÄ«yÄt	24.11544	54.34195	T	HLL	AE		01				0		21	Asia/Dubai	2011-11-06
+291159	QaţţÄrah	Qattarah	Al-Qatarah,Qatara,Qatarah,Qattara,Qattarah,QatÄrah,QaţţÄrah,Qaá¹­á¹­Ära	24.25993	55.75566	P	PPL	AE		01				0		292	Asia/Dubai	2011-11-06
+291160	Ţawī Qaţam	Tawi Qatam	Tawi Qatam,Ţawī Qaţam	24.0525	54.74417	H	WLL	AE		01				0		74	Asia/Dubai	2011-11-06
+291161	Qaţam	Qatam	Qatam,Qaţam	24.0532	54.73458	T	DUNE	AE		01				0		74	Asia/Dubai	2011-11-06
+291162	Qataiwa	Qataiwa	Qataiwa	23.41667	55.28333	H	WLL	AE		01				0		155	Asia/Dubai	2011-11-06
+291163	Qassīs Ḩayy	Qassis Hayy	Qassis Haiy,Qassis Hayy,Qassīs Haiy,Qassīs Ḩayy	24.1	55.63333	T	DPR	AE	AE	01				0		250	Asia/Dubai	2011-11-06
+291164	Ramlat al Qassīs	Ramlat al Qassis	Ramlat al Qassis,Ramlat al Qassīs	24.08333	55.58333	T	DUNE	AE		01				0		238	Asia/Dubai	2011-11-06
+291165	QaÅŸÅŸÄbÄ«	Qassabi	Gassabi,GassÄbi,Jassabi,JaÅŸÅŸÄbÄ«,Qassabi,QaÅŸÅŸÄbÄ«,Qusabi,QuÅŸÄbÄ«,Umm al Majarib,Umm al MajÄrib	24.21093	54.1017	T	ISL	AE		01				0		11	Asia/Dubai	2011-11-06
+291166	QaÅŸr ÅžÄliḩ	Qasr Salih	Qasr Salih,QaÅŸr ÅžÄliḩ	23.92871	52.78831	T	SAND	AE		01				0		43	Asia/Dubai	2011-11-06
+291167	WÄdÄ« Qasmah	Wadi Qasmah	Wadi Qasma,Wadi Qasmah,WÄdÄ« Qasma,WÄdÄ« Qasmah	24.48968	55.53049	H	WAD	AE		01				0		251	Asia/Dubai	2011-11-06
+291168	Kharīmat Qaşīmah	Kharimat Qasimah	Kharimat Qasimah,Kharmat Qasimah,Kharmat Qaşīmah,Kharīmat Qaşīmah,Qasimah,Qaşimah	24.07524	54.89174	T	TRGD	AE		01				0		90	Asia/Dubai	2011-11-06
+291169	QaÅŸÄ«mah	Qasimah	Qasimah,QaÅŸÄ«mah	24.05154	54.90686	H	WLL	AE		01				0		83	Asia/Dubai	2011-11-06
+291170	Qarn Qashash	Qarn Qashash	Qarn Qashash	24.42261	55.59755	T	HLL	AE		01				0		275	Asia/Dubai	2011-11-06
+291171	Qarqarī	Qarqari	Qarqari,Qarqarī	24.31889	55.61222	T	DPR	AE		01				0		221	Asia/Dubai	2011-11-06
+291172	Qarnayn	Qarnayn	Al Qarnain,Al Qarnayn,Jazirat al Qarnayn,Jazīrat al Qarnayn,Jezirat Qarnain,Karnain Island,Qarnayn,Qarnein	24.93528	52.84972	T	ISL	AE	AE	01				0		-9999	Asia/Dubai	2011-11-06
+291173	Qarḩat Suwayd	Qarhat Suwayd	Qarhat Suwaid,Qarhat Suwayd,Qarḩat Suwayd	24.5	55.68333	V	TREE	AE	AE	01				0		286	Asia/Dubai	2011-11-06
+291174	WÄdÄ« Qarḩah	Wadi Qarhah	Wadi Qarhah,WÄdÄ« Qarḩah	25.36471	55.8084	T	DPR	AE		06				0		80	Asia/Dubai	2011-11-06
+291175	Sayḩ QarÄţīs	Sayh Qaratis	Sayh Qaratis,Sayḩ QarÄţīs	24.86667	55.55	T	DPR	AE		03				0		148	Asia/Dubai	2011-11-06
+291176	Ţawī al Qaran	Tawi al Qaran	Tawi al Qaran,Ţawī al Qaran	25.53317	55.74746	H	WLL	AE		07				0		49	Asia/Dubai	2011-11-06
+291177	QarÄmidah	Qaramidah	Qaramidah,QarÄmidah	23.14517	53.71552	L	OAS	AE		01				0		160	Asia/Dubai	2011-11-06
+291178	Å¢awÄ« al QÄrah	Tawi al Qarah	Alcara,Tawi al Qarah,Å¢awÄ« al QÄrah	25.69146	56.00238	H	WLL	AE		05				0		15	Asia/Dubai	2011-11-06
+291179	Qar‘ah	Qar`ah	Qar'a,Qar`ah,Qara'a,Qara’a,Qar‘ah,Qar’a	24.9	55.03333	T	SAND	AE		03				0		16	Asia/Dubai	2011-11-06
+291180	Å¢awÄ« Qarad	Tawi Qarad	Tawi Garhad,Tawi Qarad,Å¢awÄ« Qarad,Å¢ÄwÄ« Garhad	25.62735	55.75506	H	WLL	AE		07				0		23	Asia/Dubai	2011-11-06
+291181	Khawr Qanţūr	Khawr Qantur	Khawr Qantur,Khawr Qanţūr	24.15843	54.06167	H	CHNM	AE		01				0		-9999	Asia/Dubai	2011-11-06
+291182	Qamshī	Qamshi	Qamshi,Qamshī,Qemshi	24.74458	54.77306	T	HLL	AE		01				0		12	Asia/Dubai	2011-11-06
+291183	QamrÄ’	Qamra'	Qamra',QamrÄ’	23.03861	52.60583	H	WLL	AE		01				0		103	Asia/Dubai	2011-11-06
+291184	QamrÄ’	Qamra'	Qamra',QamrÄ’	23.01254	52.48934	L	LCTY	AE		01				0		85	Asia/Dubai	2011-11-06
+291185	Qamarah	Qamarah	Qamarah	23.71667	53.4	T	HLL	AE		01				0		81	Asia/Dubai	2011-11-06
+291186	Jabal al Qumr ash ShamÄlÄ«	Jabal al Qumr ash Shamali	Jabal al Qamar,Jabal al Qumr ash Shamali,Jabal al Qumr ash ShamÄlÄ«	25.46168	56.04501	T	MT	AE		05				0		561	Asia/Dubai	2011-11-06
+291187	Jabal al Qumr al Janūbī	Jabal al Qumr al Janubi	Jabal al Qamar,Jabal al Qumr al Janubi,Jabal al Qumr al Janūbī	25.43354	56.044	T	MT	AE		05				0		455	Asia/Dubai	2011-11-06
+291188	WÄdÄ« al QildÄ«	Wadi al Qildi	Wadi al Qaliddi,Wadi al Qildi,WÄdÄ« al QaliddÄ«,WÄdÄ« al QildÄ«	25.59763	55.98951	H	WAD	AE		04				0		36	Asia/Dubai	2011-11-06
+291189	WÄdÄ« al QaliddÄ«	Wadi al Qaliddi	Wadi al Qaliddi,WÄdÄ« al QaliddÄ«	25.56667	56.05	H	WAD	AE		04				0		346	Asia/Dubai	2011-11-06
+291190	‘Aqabat al QaliddÄ«	`Aqabat al Qaliddi	Qalidda Pass,Qaliddi Pass,QÄliddi Pass,`Aqabat al Qaliddi,‘Aqabat al QaliddÄ«	25.53387	56.12393	T	PASS	AE		04				0		512	Asia/Dubai	2011-11-06
+291191	Qaiyaisha	Qaiyaisha	Qaiyaisha	25.88333	56.11667	L	TRB	AE		05				0		853	Asia/Dubai	2011-11-06
+291192	Ḩabl QÄ’imah	Habl Qa'imah	Habl Qa'im,Habl Qa'imah,Habl Qa’im,Ḩabl QÄ’imah	24.35345	54.73194	T	SAND	AE		01				0		46	Asia/Dubai	2011-11-06
+291193	QÄ’imah	Qa'imah	Gaimo,Qa'imah,QÄ’imah	24.32635	54.7658	H	WLLS	AE		01				0		53	Asia/Dubai	2011-11-06
+291194	Raml al Qaḩţ	Raml al Qaht	Raml al Qaht,Raml al Qaḩţ	24.73333	55.28333	T	SAND	AE		03				0		115	Asia/Dubai	2011-11-06
+291195	Ţawī Qafan	Tawi Qafan	Tawi Qafan,Ţawī Qafan	25.29778	55.88472	H	WLL	AE		06				0		118	Asia/Dubai	2011-11-06
+291196	WÄdÄ« Qada‘ah	Wadi Qada`ah	Wadi Ghayl,Wadi Qada`a,Wadi Qada`ah,Wadi Qadda`a,WÄdÄ« Qada‘a,WÄdÄ« Qada‘ah,WÄdÄ« Qadda‘a	25.79083	56.07842	H	WAD	AE		05				0		203	Asia/Dubai	2011-11-06
+291197	Jabal Qada‘ah	Jabal Qada`ah	Jabal Qada`a,Jabal Qada`ah,Jabal Qada‘a,Jabal Qada‘ah	25.77944	56.13973	T	MT	AE		05				0		1374	Asia/Dubai	2011-11-06
+291198	Qada‘ah	Qada`ah	Qada`a,Qada`ah,Qada‘a,Qada‘ah	25.76667	56.08333	V	CULT	AE		05				0		379	Asia/Dubai	2011-11-06
+291199	Qabas	Qabas	Qabas	26.03435	56.12302	P	PPL	AE		05				0		419	Asia/Dubai	2011-11-06
+291200	Qubaythah	Qubaythah	Qabaitha,Qubaythah	24.41472	55.69599	L	LCTY	AE		01				0		318	Asia/Dubai	2011-11-06
+291201	Petty Patches	Petty Patches	Petty Patches	24.48392	52.4424	H	SHOL	AE		01				0		-9999	Asia/Dubai	2011-11-06
+291204	NuwayrÄn	Nuwayran	Nuwayran,NuwayrÄn	24.0781	54.66495	T	DUNE	AE		01				0		56	Asia/Dubai	2011-11-06
+291205	Ţawī Nuşaylī	Tawi Nusayli	Tawi Nusayli,Ţawī Nuşaylī	24.34467	55.22058	H	WLLS	AE		01				0		133	Asia/Dubai	2011-11-06
+291206	Sabkhat Nuşaylī	Sabkhat Nusayli	Sabkhat Nusayli,Sabkhat Nuşaylī	24.32398	55.1741	H	SBKH	AE		01				0		124	Asia/Dubai	2011-11-06
+291207	Qarn NuÅŸaylah	Qarn Nusaylah	Al-Neseilah,Qarn Nusaylah,Qarn NuÅŸaylah	24.46222	54.63361	T	DUNE	AE	AE	01				0		14	Asia/Dubai	2011-11-06
+291208	NuÅŸayb	Nusayb	Nusayb,NuÅŸayb	24.45	55.11667	T	TRGD	AE		01				0		123	Asia/Dubai	2011-11-06
+291209	Nuqayrah	Nuqayrah	Nuqayrah	23.30021	54.09107	P	PPL	AE		01				0		172	Asia/Dubai	2011-11-06
+291210	Nuqaydhah	Nuqaydhah	Nuqaydhah	23.02418	53.56632	T	DPR	AE		01				0		77	Asia/Dubai	2011-11-06
+291211	Ţawī Numayrīyah	Tawi Numayriyah	Nimairiya,Numairiya,Tawi Nimairiyyah,Tawi Numayriyah,Ţawī Numayrīyah	23.75469	54.42187	H	WLL	AE		01				0		104	Asia/Dubai	2011-11-06
+291212	Numayl	Numayl	Nemail,Numayl	23.13487	53.88304	L	OAS	AE		01				0		106	Asia/Dubai	2011-11-06
+291213	Å¢awÄ« an Nukharah	Tawi an Nukharah	Tawi Nakh,Tawi an Nakharah,Tawi an Nukharah,Å¢awÄ« an Nakharah,Å¢awÄ« an Nukharah,ṬÄwÄ« Nakh	24.93857	55.39779	H	WLL	AE		03				0		83	Asia/Dubai	2011-11-06
+291214	Sayḩ an Nukharah	Sayh an Nukharah	Sayh an Nakharah,Sayh an Nukharah,Sayḩ an Nakharah,Sayḩ an Nukharah	24.93333	55.35	T	TRGD	AE	AE	03				0		71	Asia/Dubai	2011-11-06
+291215	Nuhayy	Nuhayy	Nahai,Nuhayy	25.27074	56.36242	P	PPL	AE		06				0		22	Asia/Dubai	2011-11-06
+291216	Ţawī Nubayy	Tawi Nubayy	Tawi Nubayy,Ţawī Nubayy	25.48333	55.71667	H	WLL	AE		07				0		45	Asia/Dubai	2011-11-06
+291217	Ţawī Nubaybigh	Tawi Nubaybigh	Nebeibighat,Tawi Nubaybigh,Tawi Nubaybighah,Ţawī Nubaybigh,Ţawī Nubaybighah	25.26667	55.81667	H	WLL	AE	AE	06				0		125	Asia/Dubai	2011-11-06
+291218	WÄdÄ« NiyÄm	Wadi Niyam	Wadi Niyam,WÄdÄ« NiyÄm	25.08412	55.92606	H	WAD	AE		05				0		185	Asia/Dubai	2011-11-06
+291219	QurÅ«n NiÅŸÄb	Qurun Nisab	Qurun Nisab,QurÅ«n NiÅŸÄb	23.80045	54.33433	T	DUNE	AE		01				0		100	Asia/Dubai	2011-11-06
+291220	NisÄb	Nisab	Nisab,NisÄb	23.79429	54.35987	H	WLL	AE		01				0		90	Asia/Dubai	2011-11-06
+291221	Nibrī	Nibri	Nibri,Nibrī	25.35176	55.84985	S	FT	AE		07				0		75	Asia/Dubai	2011-11-06
+291222	Jabal Nibah	Jabal Nibah	Jabal Nibah	24.76861	56.15111	T	MT	AE		00				0		522	Asia/Dubai	2011-11-06
+291223	WÄdÄ« Nazwá	Wadi Nazwa	Wadi Nazwa,WÄdÄ« Nazwá	25.01163	55.65579	T	TRGD	AE		06				0		176	Asia/Dubai	2011-11-06
+291224	Å¢awÄ« Nazwá	Tawi Nazwa	Nazwa,NazwÄ,Tawi Nazwa,Tawi Nezwa,Tawi Nizwa,Å¢awÄ« Nazwá,Å¢ÄwÄ« Nezwa	25.0325	55.68361	H	WLL	AE	AE	06				0		168	Asia/Dubai	2011-11-06
+291225	Qarn Nazwá	Qarn Nazwa	Qarn Nazwa,Qarn Nazwá,Qarn Nizwa	24.98371	55.66235	T	HLL	AE		00				0		173	Asia/Dubai	2011-11-06
+291226	WÄdÄ« NayÄs	Wadi Nayas	Wadi Nayas,Wadi Nayassa,WÄdÄ« Nayassa,WÄdÄ« NayÄs	25.02082	55.9848	H	WAD	AE		05				0		247	Asia/Dubai	2011-11-06
+291227	NaqÄ an NawÄ	Naqa an Nawa	Naqa Nawi,Naqa an Nawa,NaqÄ NÄwÄ«,NaqÄ an NawÄ	25.14487	55.42354	T	DUNE	AE		03				0		55	Asia/Dubai	2011-11-06
+291228	Sayḩ Naşūrīyah Ghafanī	Sayh Nasuriyah Ghafani	Sayh Nasuriyah Ghafani,Sayh Nisuriyah,Sayḩ Naşūrīyah Ghafanī,Sayḩ Nişūrīyah	24.39117	55.2855	T	TRGD	AE		01				0		155	Asia/Dubai	2011-11-06
+291229	Ţawī Naşūrīyah	Tawi Nasuriyah	Tawi Nasuriyah,Tawi Nisuriyah,Ţawī Naşūrīyah,Ţawī Nişūrīyah	24.32521	55.35583	H	WLL	AE		01				0		146	Asia/Dubai	2011-11-06
+291230	Sayḩ Naşūrīyah	Sayh Nasuriyah	Sayh Nasuriyah,Sayh Nisuriyah,Sayḩ Naşūrīyah,Sayḩ Nişūrīyah	24.36214	55.35931	T	TRGD	AE		01				0		179	Asia/Dubai	2011-11-06
+291231	Naşūrīyah	Nasuriyah	Nasuriyah,Naşūrīyah,Ryah Nisuh	24.4	55.31667	H	WLL	AE	AE	01				0		100	Asia/Dubai	2011-11-06
+291232	Naşūrīyah	Nasuriyah	Nasuriyah,Naşūrīyah,Nisuriyah,Nişūrīyah	24.36667	55.41667	T	DUNE	AE	AE	01				0		184	Asia/Dubai	2011-11-06
+291233	NaÅŸlah	Naslah	Naslah,NaÅŸlah	23.82234	52.6032	T	SAND	AE		01				0		62	Asia/Dubai	2011-11-06
+291234	NaÅŸÄ«b	Nasib	Nasib,NaÅŸÄ«b	24.56667	55.16667	T	DUNE	AE		01				0		92	Asia/Dubai	2011-11-06
+291235	Nashimah	Nashimah	Nashimah	23.09103	53.80754	T	DPR	AE		01				0		81	Asia/Dubai	2011-11-06
+291236	Sayḩ an Nashash	Sayh an Nashash	Sayh an Nashash,Sayḩ an Nashash,Sih al Nashash,Sih an Nashash,Sīḩ an NashÄsh	24.08865	55.71184	T	TRGD	AE		01				0		245	Asia/Dubai	2011-11-06
+291237	Milhala	Milhala	Milhala,Tawi Nasas,Å¢awÄ« Nasas,Å¢awÄ« NaÅŸÄÅŸ	25.02694	55.97	H	WLL	AE		05				0		265	Asia/Dubai	2011-11-06
+291238	Ramlat NasÄs	Ramlat Nasas	Ramlat Nasas,Ramlat NasÄs	24.51593	55.168	T	DUNE	AE		01				0		106	Asia/Dubai	2011-11-06
+291239	Nasas	Nasas	Nasas	24.5	55.18333	T	TRGD	AE		01				0		125	Asia/Dubai	2011-11-06
+291240	Ţawī Naqrah	Tawi Naqrah	Tawi Nagarah,Tawi Naqara,Tawi Naqrah,Ţawī Naqara,Ţawī Naqrah	24.3762	55.53108	H	WLLS	AE		01				0		194	Asia/Dubai	2011-11-06
+291241	Qarn Naqrah	Qarn Naqrah	Qarn Naqrah	24.37348	55.52974	T	DUNE	AE		01				0		235	Asia/Dubai	2011-11-06
+291242	Naqrah	Naqrah	Naqrah	24.37644	55.56032	P	PPL	AE		01				0		247	Asia/Dubai	2011-11-06
+291243	Naqrah	Naqrah	Naqrah	24.38333	55.45	T	DUNE	AE		01				0		204	Asia/Dubai	2011-11-06
+291244	Naqbīyīn	Naqbiyin	Naqbiyin,Naqbīyīn	25.66667	56	L	TRB	AE		00				0		12	Asia/Dubai	2011-11-06
+291245	Naqbiyīn	Naqbiyin	Naqbiyin,Naqbiyīn	25.33333	56.33333	L	TRB	AE		00				0		426	Asia/Dubai	2011-11-06
+291246	WÄdÄ« Naqat	Wadi Naqat	Wadi Naqat,WÄdÄ« Naqat	25.86667	56.1	H	WAD	AE		05				0		205	Asia/Dubai	2011-11-06
+291247	Jaww an NÄqah	Jaww an Naqah	Jaww an Naqah,Jaww an NÄqah	22.96387	54.14931	T	DPR	AE		01				0		95	Asia/Dubai	2011-11-06
+291248	Naqab Sha‘rÄn	Naqab Sha`ran	Naqab Sha`ran,Naqab Sha‘rÄn	24.17121	54.66632	T	SAND	AE		01				0		44	Asia/Dubai	2011-11-06
+291249	WÄdÄ« Naqab	Wadi Naqab	Wadi Naqab,WÄdÄ« Naqab	25.70384	56.0662	H	WAD	AE		05				0		85	Asia/Dubai	2011-11-06
+291250	Namlīyah	Namliyah	Namliyah,Namlīyah	23.05915	53.958	T	DPR	AE		01				0		170	Asia/Dubai	2011-11-06
+291251	Namlīyah	Namliyah	Namliyah,Namlīyah	23.03453	54.02193	T	DPR	AE		01				0		87	Asia/Dubai	2011-11-06
+291252	Namlah	Namlah	Namlah	23.06497	53.97529	H	WLL	AE		01				0		76	Asia/Dubai	2011-11-06
+291253	Namlah	Namlah	Namalah,Namlah	23.01393	53.47494	T	DPR	AE		01				0		172	Asia/Dubai	2011-11-06
+291254	Nakhl Subayyis	Nakhl Subayyis	Nakhl Sibaiyis,Nakhl Sibaylis,Nakhl Subaiyis,Nakhl Subayyis	24.3575	55.20611	V	TREE	AE	AE	01				0		107	Asia/Dubai	2011-11-06
+291255	Nakhl Bin JirwÄn	Nakhl Bin Jirwan	Nakhl Bin Jirwan,Nakhl Bin JirwÄn,Nakhl bin Jerwan	24.18333	55.11667	H	WLLS	AE	AE	01				0		123	Asia/Dubai	2011-11-06
+291256	‘Uqlat an Nakhlah	`Uqlat an Nakhlah	An Nakhlah,Nakhla,`Uglat Nakhlan,`Uqlat al-Nakhlah,`Uqlat an Nakhlah,‘Uglat Nakhlan,‘Uqlat al-Nakhlah,‘Uqlat an Nakhlah	24.31667	51.2	H	WLL	AE		01				0		7	Asia/Dubai	2011-11-06
+291257	Ramlat an Nakhlah	Ramlat an Nakhlah	Ramlat an Nakhlah	24.35861	51.20632	T	DUNE	AE		01				0		10	Asia/Dubai	2011-11-06
+291258	Nakhalai	Nakhalai	Nakhalai	25.09528	55.57653	L	LCTY	AE		03				0		89	Asia/Dubai	2011-11-06
+291259	Jabal Najla‘	Jabal Najla`	Jabal Najla`,Jabal Najla‘	25.43593	55.99124	T	HLL	AE		05				0		208	Asia/Dubai	2011-11-06
+291260	Jabal Najdayn	Jabal Najdayn	Jabal Najdayn,Jabal Naydayn	25.17988	56.17201	T	MT	AE		00				0		880	Asia/Dubai	2011-11-06
+291261	Najdayn	Najdayn	Najdayn	25.16667	56.2	V	CULT	AE		04				0		639	Asia/Dubai	2011-11-06
+291262	NajdÄt	Najdat	Najadat,NajadÄt,Najdat,NajdÄt	24.13333	55.91667	L	TRB	AE	AE	01				0		378	Asia/Dubai	2011-11-06
+291263	Na‘ītah	Na`itah	Jazirat Na`itah,Jazīrat Na‘ītah,Na`itah,Naita,Na‘ītah,Ne'ita,Ne’īta,Ni`eitah,Ni‘eitah	24.29085	51.79455	T	ISL	AE		01				0		-9999	Asia/Dubai	2011-11-06
+291264	NaqÄ NÄ’if	Naqa Na'if	Naqa Na'if,NaqÄ NÄ’if	23.08742	55.22844	T	DUNE	AE		01				0		171	Asia/Dubai	2011-11-06
+291265	Nahwá	Nahwa	Nahawa,Nahwa,Nahwá	25.26823	56.28002	P	PPL	AE		06				0		213	Asia/Dubai	2011-11-06
+291266	Ţawī Nahshīlah	Tawi Nahshilah	Tawi Nahshilah,Ţawī Nahshīlah	24.40832	55.10681	H	WLL	AE		01				0		103	Asia/Dubai	2011-11-06
+291267	Nahshīlah	Nahshilah	Nahshilah,Nahshīlah	24.4032	55.05936	T	SAND	AE		01				0		100	Asia/Dubai	2011-11-06
+291268	Nahdayn	Nahdayn	Nahdain,Nahdayn,Nahdein	23.68333	52.3	S	OILW	AE	AE	01				0		41	Asia/Dubai	2011-11-06
+291269	Nahdayn	Nahdayn	Nahadain,Nahdayn	23.68725	52.30246	T	HLL	AE		01				0		49	Asia/Dubai	2011-11-06
+291270	Nafīr	Nafir	Nafir,Nafīr,Nefair	23.10393	53.78919	P	PPL	AE		01				0		86	Asia/Dubai	2011-11-06
+291271	Nafīr	Nafir	Nafir,Nafīr	23.10444	53.78667	T	DPR	AE		01				0		86	Asia/Dubai	2011-11-06
+291272	NaqÄ Nadh	Naqa Nadh	Naqa Nadh,NaqÄ Nadh	23.79851	55.49041	T	DUNE	AE		01				0		194	Asia/Dubai	2011-11-06
+291273	Nadd Umm Ḩaşá	Nadd Umm Hasa	Nadd Umm Hasa,Nadd Umm Ḩaşá	25.13954	55.38266	L	LCTY	AE		03				0		20	Asia/Dubai	2011-11-06
+291274	Nadd MÄni‘	Nadd Mani`	Nadd Mani`,Nadd MÄni‘,Ned Bin Tamana,Nidd Mani`,Nidd MÄni‘	25.55306	55.5475	T	PEN	AE		07				0		18	Asia/Dubai	2011-11-06
+291275	Nadd BayḑÄ’	Nadd Bayda'	Nad Beidha,Nadd Bayda',Nadd BayḑÄ’	25.35352	55.43762	L	LCTY	AE		06				0		15	Asia/Dubai	2011-11-06
+291276	Ramlat Nadd	Ramlat Nadd	Ramlat Nadd	23.97641	55.12876	T	DUNE	AE		01				0		143	Asia/Dubai	2011-11-06
+291277	Naban	Naban	Naban	24.23824	54.90422	H	WLL	AE		01				0		77	Asia/Dubai	2011-11-06
+291278	Na‘adhal	Na`adhal	Na`adhal,Na‘adhal	22.98454	53.54606	T	DPR	AE		01				0		46	Asia/Dubai	2011-11-06
+291279	Muzayri‘	Muzayri`	Mezaira'a,Mezaira’a,Mizeir`ah,Mizeir‘ah,Mozayri`,Mozayri‘,Muzayri`,Muzayri‘	23.14355	53.7881	P	PPL	AE		01				10000		181	Asia/Dubai	2011-11-06
+291280	Mughaylat MuzÄri‘	Mughaylat Muzari`	Maghailat Muzaria,Mughaylat Muzari`,Mughaylat MuzÄri‘	24.03333	54.95	H	WLL	AE		01				0		90	Asia/Dubai	2011-11-06
+291281	GhÄfat al Muyayridah	Ghafat al Muyayridah	Ghafat al Muyayridah,GhÄfat al Muyayridah	25.6	56.3	H	WLL	AE		04				0		45	Asia/Dubai	2011-11-06
+291282	Sayḩ Muyaydirah	Sayh Muyaydirah	Sayh Muyaydirah,Sayḩ Muyaydirah	24.68333	55.4	T	TRGD	AE		03				0		155	Asia/Dubai	2011-11-06
+291283	Muyaydirah	Muyaydirah	Muyaydirah	24.7	55.38333	T	SAND	AE		03				0		118	Asia/Dubai	2011-11-06
+291284	NaqÄ Muwayzah	Naqa Muwayzah	Naqa Muwayzah,NaqÄ Muwayzah	24.6	55.31667	T	SAND	AE		01				0		135	Asia/Dubai	2011-11-06
+291285	Ḩişn al Muwayqi‘ī	Hisn al Muwayqi`i	Hisn al Muwayqi`i,Ḩişn al Muwayqi‘ī	24.21667	55.71667	S	FT	AE		01				0		266	Asia/Dubai	2011-11-06
+291286	Muwayliḩ	Muwaylih	Muailah,Muwaylih,Muwayliḩ	24.61506	54.7728	H	WLL	AE		01				0		24	Asia/Dubai	2011-11-06
+291287	WÄdÄ« al Muwayji‘ah	Wadi al Muwayji`ah	Wadi al Muwayji`ah,WÄdÄ« al Muwayji‘ah	24.95	55.4	T	DPR	AE		03				0		85	Asia/Dubai	2011-11-06
+291288	Muwayh Arnab	Muwayh Arnab	Muwayh Arnab	24.27467	55.05049	T	SAND	AE		01				0		123	Asia/Dubai	2011-11-06
+291289	Muwayh al Ju’Äbir	Muwayh al Ju'abir	Muwayh al Ju'abir,Muwayh al Ju’Äbir	23.82211	55.46188	T	DUNE	AE		01				0		181	Asia/Dubai	2011-11-06
+291290	Muwayh al Huḑayb	Muwayh al Hudayb	Muwayh al Hudayb,Muwayh al Huḑayb	24.06076	55.35169	T	SAND	AE		01				0		191	Asia/Dubai	2011-11-06
+291291	Bi’r Muwayfiqah	Bi'r Muwayfiqah	Bi'r Muwayfiqah,Bi’r Muwayfiqah,Muwafiqa,Muwafiqah,MuwÄfiqa,MuwÄfÄ«qah	24.13194	55.68139	H	WLL	AE		01				0		247	Asia/Dubai	2011-11-06
+291292	Jabal Muthrad	Jabal Muthrad	Jabal Muthrad	25.15731	56.28963	T	MT	AE		04				0		387	Asia/Dubai	2011-11-06
+291293	Ţawī Mutayn	Tawi Mutayn	Tawi Mutayn,Ţawī Mutayn	23.2725	53.60472	H	WLL	AE		01				0		141	Asia/Dubai	2011-11-06
+291294	MuÅ£aylÄn	Mutaylan	Mitailan,Mutailan,Mutaylan,MuÅ£aylÄn	23.84996	53.82125	L	AREA	AE		01				0		69	Asia/Dubai	2011-11-06
+291295	Mughayyil Muţawwá	Mughayyil Mutawwa	Mughayyil Mutawwa,Mughayyil Muţawwá	24.06546	54.89046	H	WLL	AE		01				0		107	Asia/Dubai	2011-11-06
+291296	Bid‘ al MuÅ£Äwa‘ah	Bid` al Mutawa`ah	Bid' al-Mataw'a,Bid` al Mutawa`ah,Bid` al Mutawwa`,Bid` al-Mataw`ah,Bid‘ al MuÅ£awwa‘,Bid‘ al MuÅ£Äwa‘ah,Bid‘ al-Maá¹­Äw‘ah,Bid’ al-Mataw’a	23.75972	52.51917	H	WLL	AE		01				0		68	Asia/Dubai	2011-11-06
+291297	WÄdÄ« Mu‘tariḑah	Wadi Mu`taridah	Wadi Mu`taridah,WÄdÄ« Mu‘tariḑah	25.5165	56.00264	H	WAD	AE		00				0		97	Asia/Dubai	2011-11-06
+291298	Mu‘tariḑah	Mu`taridah	Mu`taridah,Mu`taridat,Mu‘tariḑah,Mu‘tariḑat	23.93178	52.41949	T	RKS	AE		01				0		58	Asia/Dubai	2011-11-06
+291299	Mu‘tariḑah	Mu`taridah	Mu`taridah,Mu‘tariḑah	25.50841	56.11046	P	PPL	AE		04				0		350	Asia/Dubai	2011-11-06
+291300	Mu‘tariḑah	Mu`taridah	Mu`taridah,Mu‘tariḑah	24.03558	53.34833	T	HLLS	AE		01				0		18	Asia/Dubai	2011-11-06
+291301	Mu‘tariḑah	Mu`taridah	Mu`taridah,Mu‘tariḑah	23.92444	52.43222	T	DUNE	AE		01				0		38	Asia/Dubai	2011-11-06
+291302	Jabal Mu‘tariḑ	Jabal Mu`tarid	Jabal Ma'atridh,Jabal Ma’atridh,Jabal Mu`tarid,Jabal Mu‘tariḑ	25.45641	55.99319	T	HLL	AE		05				0		233	Asia/Dubai	2011-11-06
+291303	Bid‘ Mussama	Bid` Mussama	Bid` Mussama,Bid‘ Mussama	23.55	53.61667	H	WLL	AE		01				0		128	Asia/Dubai	2011-11-06
+291304	Musaqab	Musaqab	Musaqab,Musqab	25.16778	56.14167	V	GRVP	AE	AE	05				0		363	Asia/Dubai	2011-11-06
+291305	Mushrif	Mushrif	Mushrif	25.21667	55.45	H	WLL	AE		03				0		34	Asia/Dubai	2011-11-06
+291306	Ţawī Mushayrif	Tawi Mushayrif	Mashairif,Mushairif,Tawi Mushayrif,Ţawī Mushayrif	24.08689	54.81192	H	WLL	AE		01				0		76	Asia/Dubai	2011-11-06
+291307	Sabkhat Mushayrif	Sabkhat Mushayrif	Sabkhat Mushayrif	24.15149	54.66116	H	SBKH	AE		01				0		40	Asia/Dubai	2011-11-06
+291308	Mushayrif	Mushayrif	Mushayrif	23.92507	54.31447	T	TRGD	AE		01				0		81	Asia/Dubai	2011-11-06
+291309	Mushayrif	Mushayrif	Mushairif,Mushayrif	24.11525	54.81618	L	LCTY	AE		01				0		84	Asia/Dubai	2011-11-06
+291310	Mushayrif	Mushayrif	Mushayrif	24.11489	54.66871	T	DUNE	AE		01				0		57	Asia/Dubai	2011-11-06
+291311	Ra’s Mushayrib	Ra's Mushayrib	Ra's Mashayrib,Ra's Mushayrib,Ras Mashairif,Ras Masheirib,Ras Masherib,Ras Mushairib,Ras Musheirib,Ra’s Mashayrib,Ra’s Mushayrib,RÄs Mushairib	24.29292	51.74242	T	PT	AE		01				0		-9999	Asia/Dubai	2011-11-06
+291312	Mushayrib	Mushayrib	Mushayrib	24.46667	54.41667	T	ISL	AE		01				0		-9999	Asia/Dubai	2011-11-06
+291313	MushÄshÄ«	Mushashi	Mashashi,Mushashi,MushÄshÄ«	23.11124	52.5636	S	OILW	AE		01				0		114	Asia/Dubai	2011-11-06
+291314	MushÄsh	Mushash	Imshash,Mushash,MushÄsh	24.55769	51.35768	H	WLL	AE		01				0		-9999	Asia/Dubai	2011-11-06
+291315	MushÄjir	Mushajir	Mushajir,MushÄjir	23.08605	53.99163	L	OAS	AE		01				0		178	Asia/Dubai	2011-11-06
+291316	MushÄjir	Mushajir	Mushajir,MushÄjir	23.07049	53.93374	T	DPR	AE		01				0		73	Asia/Dubai	2011-11-06
+291317	Bid‘ Muşfir	Bid` Musfir	Bid` Musfir,Bid‘ Muşfir,Bir Misfar	24.0619	55.29648	H	WLL	AE		01				0		175	Asia/Dubai	2011-11-06
+291318	Ruqq Musfayr	Ruqq Musfayr	Ruqq Musfayr	24.27875	51.88656	H	RF	AE		01				0		-9999	Asia/Dubai	2011-11-06
+291319	Musayyibah	Musayyibah	Musayyibah	23.82699	55.2768	T	TRGD	AE		01				0		122	Asia/Dubai	2011-11-06
+291320	Ţawī Musannad	Tawi Musannad	Tawi Musannad,Tawi Mussarad,Ţawī Musannad,Ţawī Mussarad	25.25	55.7	H	WLL	AE	AE	06				0		111	Asia/Dubai	2011-11-06
+291321	Sayḩ Musannad	Sayh Musannad	Sayh Musannad,Sayḩ Musannad	25.25104	55.67154	T	TRGD	AE		06				0		71	Asia/Dubai	2011-11-06
+291322	WÄdÄ« MusallÄ	Wadi Musalla	Wadi Musalla,WÄdÄ« MusallÄ	25.51575	56.00944	H	WAD	AE		04				0		142	Asia/Dubai	2011-11-06
+291323	Ḩadd Musafsif	Hadd Musafsif	Hadd Musafsif,Ḩadd Musafsif	24.10083	52.06417	H	SHOL	AE		01				0		-9999	Asia/Dubai	2011-11-06
+291324	Khawr Musá	Khawr Musa	Khawr Musa,Khawr Musá	22.725	53.51671	T	DPR	AE		01				0		62	Asia/Dubai	2011-11-06
+291325	Sayḩ Muruq	Sayh Muruq	Sayh Muruq,Sayḩ Muruq	25.56617	56.0731	T	DPR	AE		04				0		211	Asia/Dubai	2011-11-06
+291326	WÄdÄ« Murtaqam	Wadi Murtaqam	Wadi Murtaqam,Wadi Murtaqau,WÄdÄ« Murtaqam,WÄdÄ« Murtaqau	25.36727	56.25448	H	WAD	AE		04				0		277	Asia/Dubai	2011-11-06
+291327	WÄdÄ« Murrah	Wadi Murrah	Wadi Murrah,WÄdÄ« Murrah	25.19803	56.22673	H	WAD	AE		04				0		321	Asia/Dubai	2011-11-06
+291328	WÄdÄ« Murrah	Wadi Murrah	Wadi Murrah,WÄdÄ« Murrah	24.9	55.43333	T	TRGD	AE		03				0		105	Asia/Dubai	2011-11-06
+291329	Å¢awÄ« Murrah	Tawi Murrah	Al-Murrah,Qa`r Murra,Qa‘r Murra,Tawi Murra,Tawi Murrah,Å¢awÄ« Murrah,Å¢ÄwÄ« Murra	25.13443	55.74992	H	WLL	AE		06				0		117	Asia/Dubai	2011-11-06
+291330	Ţawī Murrah	Tawi Murrah	Tawi Morro,Tawi Motto,Tawi Murra,Tawi Murrah,Ţawī Murrah	24.90846	55.44146	H	WLL	AE		03				0		113	Asia/Dubai	2011-11-06
+291331	Raml Murrah	Raml Murrah	Raml Murrah	24.86266	55.38085	T	SAND	AE		03				0		80	Asia/Dubai	2011-11-06
+291332	Qarn Murrah	Qarn Murrah	Qarat Murra,Qarat Murrah,Qarn Murrah,QÄrat Murra,QÄrat Murrah	25.13349	55.7703	T	DUNE	AE		06				0		150	Asia/Dubai	2011-11-06
+291333	Murrah	Murrah	Murrah	25.03333	55.6	V	TREE	AE		03				0		162	Asia/Dubai	2011-11-06
+291334	Murrah	Murrah	Murrah	25.19903	56.22165	P	PPL	AE		04				0		223	Asia/Dubai	2011-11-06
+291335	Muriya HammÄmah	Muriya Hammamah	Muriya Hammamah,Muriya HammÄmah	24.93333	54.26667	T	RKS	AE		01				0		-9999	Asia/Dubai	2011-11-06
+291336	Ḩaql MurbÄn	Haql Murban	Haql Murban,Mirban,Murban Field,Ḩaql MurbÄn	23.83333	53.75	L	OILF	AE	AE	01				0		76	Asia/Dubai	2011-11-06
+291337	MurbÄn	Murban	Mirban,MirbÄn,Murban,MurbÄn	23.95342	53.69134	T	HLL	AE		01				0		3	Asia/Dubai	2011-11-06
+291338	Sabkhat Murbaḩ	Sabkhat Murbah	Sabkhat Murbah,Sabkhat Murbaḩ	25.25	56.36667	H	SBKH	AE		04				0		-9999	Asia/Dubai	2011-11-06
+291339	Murbaḩ	Murbah	Marbah,Mirba,Mirbih,Mirbiḥ,Murbah,Murbaḩ	25.27623	56.36256	P	PPL	AE		06				0		23	Asia/Dubai	2011-11-06
+291340	Murbaḑ	Murbad	Marbad,Murbad,Murbaḑ	25.3254	56.13311	P	PPL	AE		04				0		487	Asia/Dubai	2011-11-06
+291341	Murayyil	Murayyil	Murayyil	25.11667	55.51667	V	TREE	AE		06				0		82	Asia/Dubai	2011-11-06
+291342	Muraytah	Muraytah	Muraytah	25.40032	56.05844	P	PPL	AE		05				0		240	Asia/Dubai	2011-11-06
+291343	WÄdÄ« Murayshid	Wadi Murayshid	Wadi Murayshid,WÄdÄ« Murayshid	25.1	56.36667	H	WAD	AE		04				0		-9999	Asia/Dubai	2011-11-06
+291344	Jabal Murayshid	Jabal Murayshid	Jabal Murayshid	25.11667	56.33333	T	HLL	AE		04				0		35	Asia/Dubai	2011-11-06
+291345	Barqat Muraymīth	Barqat Muraymith	Barqat Muraymith,Barqat Muraymīth	23.88902	54.47119	T	RKS	AE		01				0		88	Asia/Dubai	2011-11-06
+291346	Muraykh	Muraykh	Maraikh,Muraykh	24	55.41667	H	WLL	AE	AE	01				0		188	Asia/Dubai	2011-11-06
+291347	Ţawī Muray	Tawi Muray	Tawi Muray,Ţawī Muray	23.86667	54.61667	H	WLL	AE		01				0		86	Asia/Dubai	2011-11-06
+291348	Å¢awÄ« MuraqqibÄt	Tawi Muraqqibat	Muraghabat,Muraqabat,Muraqqibat,Tawi Muraqqibat,Å¢awÄ« MuraqqibÄt	25.32611	55.89944	H	WLL	AE	AE	07				0		170	Asia/Dubai	2011-11-06
+291349	Ţawī Muraqqab	Tawi Muraqqab	Tawi Muraqqab,Ţawī Muraqqab	24.82029	55.58435	H	WLL	AE		03				0		182	Asia/Dubai	2011-11-06
+291350	MurÄqabÄt	Muraqabat	Muraqabat,MurÄqabÄt	25.16361	55.34111	H	WLL	AE		03				0		13	Asia/Dubai	2011-11-06
+291351	Murabba‘ah	Murabba`ah	Murabba`ah,Murabba‘ah	25.88333	56.03333	S	TOWR	AE		05				0		1	Asia/Dubai	2011-11-06
+291352	Ra’s Muqayshiţ	Ra's Muqayshit	Mughhaishat,Ra's Muqayshit,Ra's al Ibrah,Ra’s Muqayshiţ,Ra’s al Ibrah	24.16778	53.6236	T	PT	AE		01				0		-9999	Asia/Dubai	2011-11-06
+291353	Muqayshiţ	Muqayshit	Megaishit,Megeshit,Megeshiţ,Muqayshit,Muqayshiţ	24.18908	53.75226	T	ISLX	AE		01				0		10	Asia/Dubai	2011-11-06
+291354	Muqaţţarah	Muqattarah	Miqattarah,Miqaá¹­á¹­arah,Mugatara,Mugattara,Mugaţţara,Muqatirah,Muqattarah,Muqaţţarah,MuqÄtirah	24.2694	54.51333	T	HLL	AE		01				0		10	Asia/Dubai	2011-11-06
+291355	Muqala	Muqala	Muqala	23.53333	54.43333	H	WLL	AE		01				0		131	Asia/Dubai	2011-11-06
+291356	Muntahá	Muntaha	Mntaha,Muntaha,Muntahá	23.84263	55.41381	T	DPR	AE		01				0		187	Asia/Dubai	2011-11-06
+291357	Munfatrah	Munfatrah	Mufatra,Munfatrah	23.96667	53.03333	T	HLL	AE	AE	01				0		39	Asia/Dubai	2011-11-06
+291358	Mundafinah	Mundafinah	Mondafanah,Mondafinah,Mundafinah,Mundafnah	24.11667	55.8	P	PPL	AE	AE	01				0		320	Asia/Dubai	2011-11-06
+291359	Khawr ManÄ’if	Khawr Mana'if	Khawr Mana'if,Khawr ManÄ’if,Khawr Munayyif,Khor Manayef,Khor ManÄyef	24.14456	52.91494	H	COVE	AE		01				0		-9999	Asia/Dubai	2011-11-06
+291360	Munayyif	Munayyif	Munayyif	24.07278	52.94833	L	LCTY	AE		01				0		22	Asia/Dubai	2011-11-06
+291361	Munayyif	Munayyif	Munaiyif,Munayyif	24.09324	52.93446	T	HLL	AE		01				0		51	Asia/Dubai	2011-11-06
+291362	WÄdÄ« Munay‘ī	Wadi Munay`i	Wadi Manai,Wadi Munay`,Wadi Munay`i,WÄdÄ« Munay‘,WÄdÄ« Munay‘ī	24.88227	56.20944	H	WAD	AE		05				0		142	Asia/Dubai	2011-11-06
+291363	Munay‘ī	Munay`i	Manai,Manai'i,Manai’i,Munay`i,Munay‘ī	24.95135	56.14997	P	PPL	AE		05				0		370	Asia/Dubai	2011-11-06
+291364	Jabal Mulfīrah	Jabal Mulfirah	Jabal Mulfirah,Jabal Mulfīrah	25.15716	56.31601	T	HLL	AE		04				0		229	Asia/Dubai	2011-11-06
+291365	Mulaysah	Mulaysah	Mulaysah	23.91634	53.03505	H	WLL	AE		01				0		63	Asia/Dubai	2011-11-06
+291366	Mulaysah	Mulaysah	Mulaysah	23.9	53.05	H	WLL	AE		01				0		51	Asia/Dubai	2011-11-06
+291367	Mulayhim	Mulayhim	Malayham,Mulayhim	22.90126	53.43345	T	DPR	AE		01				0		54	Asia/Dubai	2011-11-06
+291368	WÄdÄ« Mulayḩah	Wadi Mulayhah	Wadi Mulayhah,WÄdÄ« Mulayḩah	25.73333	56.01667	H	WAD	AE		05				0		28	Asia/Dubai	2011-11-06
+291369	WÄdÄ« Mulayḩah	Wadi Mulayhah	Wadi Mulayhah,WÄdÄ« Mulayḩah	25.23504	55.90669	H	WAD	AE		06				0		121	Asia/Dubai	2011-11-06
+291370	Ţawī Mulayḩah	Tawi Mulayhah	Tawi Mulaiha,Tawi Mulayhah,Ţawī Mulaiha,Ţawī Mulayḩah	25.02722	55.795	H	WLL	AE	AE	06				0		161	Asia/Dubai	2011-11-06
+291371	Jabal Mulayḩah	Jabal Mulayhah	Jabal Milaiha,Jabal Mileihah,Jabal Mileiḥah,Jabal Mulayhah,Jabal Mulayḩah,Jibal Mulayhah,JibÄl Mulayḩah,Mulaiha	25.14818	55.83716	T	HLL	AE		06				0		362	Asia/Dubai	2011-11-06
+291372	Mulayḩah	Mulayhah	Mileihah,Mileiḥah,Miliaha,Mulayhah,Mulayḩah	25.16667	55.8	H	WLLS	AE	AE	06				0		158	Asia/Dubai	2011-11-06
+291373	Qarn Mulayḩ	Qarn Mulayh	Qarn Mileih,Qarn Mulayh,Qarn Mulayḩ	25.02286	55.72966	T	HLL	AE		06				0	274	236	Asia/Dubai	2011-11-06
+291374	Mukhtaraqah	Mukhtaraqah	Mahtarraqah,Muhtarqah,Mukhtaraja,Mukhtaraqah	25.54092	56.13066	P	PPL	AE		04				0		272	Asia/Dubai	2011-11-06
+291375	Mukhayūs	Mukhayus	Mukhayus,Mukhayūs	25.73222	55.95389	H	WLL	AE		05				0		47	Asia/Dubai	2011-11-06
+291376	MÅ«jib	Mujib	Mujib,MÅ«jib	23.11667	53.68333	P	PPL	AE		01				0		84	Asia/Dubai	2011-11-06
+291377	Kharmat al Muhayn	Kharmat al Muhayn	Kharimat al Mahain,Kharmat al Mahaim,Kharmat al Muhayn	23.01796	55.10773	T	DPR	AE		01				0		109	Asia/Dubai	2011-11-06
+291378	WÄdÄ« MuhaylÄ«	Wadi Muhayli	Wadi Muhayli,WÄdÄ« MuhaylÄ«	25.7044	56.06564	H	WAD	AE		05				0		85	Asia/Dubai	2011-11-06
+291379	Ţawī Muḩayjir	Tawi Muhayjir	Tawi Muhayjir,Ţawī Muḩayjir	24.5511	55.76381	H	WLL	AE		01				0		319	Asia/Dubai	2011-11-06
+291380	Jabal Muḩayjir	Jabal Muhayjir	Jabal Muhayjir,Jabal Muḩayjir,Qarn Muhaiyir	24.53819	55.73512	T	HLL	AE		01				0		293	Asia/Dubai	2011-11-06
+291381	Muhammalīyah	Muhammaliyah	Al Mahammaliyah,Jazirat Muhammaliyah,Jazīrat Muḩammalīyah,Mahamaliya,Mehammaliyya,Mehammaliyyah,Muhammaliya,Muhammaliyah,Muhammalīyah	24.11616	51.89603	T	ISL	AE		01				0		-9999	Asia/Dubai	2011-11-06
+291382	Ţawī Muḩammad	Tawi Muhammad	Tawi Muhammad,Ţawī Muḩammad	24.94636	55.75046	H	WLL	AE		06				0		183	Asia/Dubai	2011-11-06
+291383	Bid‘ Muḩammad	Bid` Muhammad	Bid` Muhammad,Bid‘ Muḩammad	24.25	55.1	H	WLL	AE		01				0		125	Asia/Dubai	2011-11-06
+291384	Qullat MuḩÄfiz̧	Qullat Muhafiz	Qal`eh Mahafidh,Qallah Mahafidh,Qal‘eh MahÄfidh,Qullat Mahafiz,Qullat MaḩÄfiz̧,Qullat Muhafiz,Qullat MuḩÄfiz̧	25.15848	55.93008	T	PLN	AE		06				0		164	Asia/Dubai	2011-11-06
+291385	Mughīlah	Mughilah	Mughila,Mughilah,Mughīlah	23.78842	55.18178	T	DPR	AE		01				0		113	Asia/Dubai	2011-11-06
+291386	Mughayyin	Mughayyin	Mughaiyin,Mughayyin	23.89196	52.78213	T	SAND	AE		01				0		69	Asia/Dubai	2011-11-06
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dataimport/test/data/timeZones.txt	Thu Dec 10 12:34:15 2015 +0100
@@ -0,0 +1,410 @@
+Africa/Abidjan	0.0	0.0	0.0
+Africa/Accra	0.0	0.0	0.0
+Africa/Addis_Ababa	3.0	3.0	3.0
+Africa/Algiers	1.0	1.0	1.0
+Africa/Asmara	3.0	3.0	3.0
+Africa/Bamako	0.0	0.0	0.0
+Africa/Bangui	1.0	1.0	1.0
+Africa/Banjul	0.0	0.0	0.0
+Africa/Bissau	0.0	0.0	0.0
+Africa/Blantyre	2.0	2.0	2.0
+Africa/Brazzaville	1.0	1.0	1.0
+Africa/Bujumbura	2.0	2.0	2.0
+Africa/Cairo	2.0	2.0	2.0
+Africa/Casablanca	0.0	1.0	0.0
+Africa/Ceuta	1.0	2.0	1.0
+Africa/Conakry	0.0	0.0	0.0
+Africa/Dakar	0.0	0.0	0.0
+Africa/Dar_es_Salaam	3.0	3.0	3.0
+Africa/Djibouti	3.0	3.0	3.0
+Africa/Douala	1.0	1.0	1.0
+Africa/El_Aaiun	0.0	0.0	0.0
+Africa/Freetown	0.0	0.0	0.0
+Africa/Gaborone	2.0	2.0	2.0
+Africa/Harare	2.0	2.0	2.0
+Africa/Johannesburg	2.0	2.0	2.0
+Africa/Kampala	3.0	3.0	3.0
+Africa/Khartoum	3.0	3.0	3.0
+Africa/Kigali	2.0	2.0	2.0
+Africa/Kinshasa	1.0	1.0	1.0
+Africa/Lagos	1.0	1.0	1.0
+Africa/Libreville	1.0	1.0	1.0
+Africa/Lome	0.0	0.0	0.0
+Africa/Luanda	1.0	1.0	1.0
+Africa/Lubumbashi	2.0	2.0	2.0
+Africa/Lusaka	2.0	2.0	2.0
+Africa/Malabo	1.0	1.0	1.0
+Africa/Maputo	2.0	2.0	2.0
+Africa/Maseru	2.0	2.0	2.0
+Africa/Mbabane	2.0	2.0	2.0
+Africa/Mogadishu	3.0	3.0	3.0
+Africa/Monrovia	0.0	0.0	0.0
+Africa/Nairobi	3.0	3.0	3.0
+Africa/Ndjamena	1.0	1.0	1.0
+Africa/Niamey	1.0	1.0	1.0
+Africa/Nouakchott	0.0	0.0	0.0
+Africa/Ouagadougou	0.0	0.0	0.0
+Africa/Porto-Novo	1.0	1.0	1.0
+Africa/Sao_Tome	0.0	0.0	0.0
+Africa/Tripoli	2.0	2.0	2.0
+Africa/Tunis	1.0	1.0	1.0
+Africa/Windhoek	2.0	1.0	1.0
+America/Adak	-10.0	-9.0	-10.0
+America/Anchorage	-9.0	-8.0	-9.0
+America/Anguilla	-4.0	-4.0	-4.0
+America/Antigua	-4.0	-4.0	-4.0
+America/Araguaina	-3.0	-3.0	-3.0
+America/Argentina/Buenos_Aires	-3.0	-3.0	-3.0
+America/Argentina/Catamarca	-3.0	-3.0	-3.0
+America/Argentina/Cordoba	-3.0	-3.0	-3.0
+America/Argentina/Jujuy	-3.0	-3.0	-3.0
+America/Argentina/La_Rioja	-3.0	-3.0	-3.0
+America/Argentina/Mendoza	-3.0	-3.0	-3.0
+America/Argentina/Rio_Gallegos	-3.0	-3.0	-3.0
+America/Argentina/Salta	-3.0	-3.0	-3.0
+America/Argentina/San_Juan	-3.0	-3.0	-3.0
+America/Argentina/San_Luis	-3.0	-3.0	-4.0
+America/Argentina/Tucuman	-3.0	-3.0	-3.0
+America/Argentina/Ushuaia	-3.0	-3.0	-3.0
+America/Aruba	-4.0	-4.0	-4.0
+America/Asuncion	-3.0	-4.0	-4.0
+America/Atikokan	-5.0	-5.0	-5.0
+America/Bahia	-3.0	-3.0	-3.0
+America/Bahia_Banderas	-6.0	-5.0	-6.0
+America/Barbados	-4.0	-4.0	-4.0
+America/Belem	-3.0	-3.0	-3.0
+America/Belize	-6.0	-6.0	-6.0
+America/Blanc-Sablon	-4.0	-4.0	-4.0
+America/Boa_Vista	-4.0	-4.0	-4.0
+America/Bogota	-5.0	-5.0	-5.0
+America/Boise	-7.0	-6.0	-7.0
+America/Cambridge_Bay	-7.0	-6.0	-7.0
+America/Campo_Grande	-3.0	-4.0	-4.0
+America/Cancun	-6.0	-5.0	-6.0
+America/Caracas	-4.5	-4.5	-4.5
+America/Cayenne	-3.0	-3.0	-3.0
+America/Cayman	-5.0	-5.0	-5.0
+America/Chicago	-6.0	-5.0	-6.0
+America/Chihuahua	-7.0	-6.0	-7.0
+America/Costa_Rica	-6.0	-6.0	-6.0
+America/Cuiaba	-3.0	-4.0	-4.0
+America/Curacao	-4.0	-4.0	-4.0
+America/Danmarkshavn	0.0	0.0	0.0
+America/Dawson	-8.0	-7.0	-8.0
+America/Dawson_Creek	-7.0	-7.0	-7.0
+America/Denver	-7.0	-6.0	-7.0
+America/Detroit	-5.0	-4.0	-5.0
+America/Dominica	-4.0	-4.0	-4.0
+America/Edmonton	-7.0	-6.0	-7.0
+America/Eirunepe	-4.0	-4.0	-4.0
+America/El_Salvador	-6.0	-6.0	-6.0
+America/Fortaleza	-3.0	-3.0	-3.0
+America/Glace_Bay	-4.0	-3.0	-4.0
+America/Godthab	-3.0	-2.0	-3.0
+America/Goose_Bay	-4.0	-3.0	-4.0
+America/Grand_Turk	-5.0	-4.0	-5.0
+America/Grenada	-4.0	-4.0	-4.0
+America/Guadeloupe	-4.0	-4.0	-4.0
+America/Guatemala	-6.0	-6.0	-6.0
+America/Guayaquil	-5.0	-5.0	-5.0
+America/Guyana	-4.0	-4.0	-4.0
+America/Halifax	-4.0	-3.0	-4.0
+America/Havana	-5.0	-4.0	-5.0
+America/Hermosillo	-7.0	-7.0	-7.0
+America/Indiana/Indianapolis	-5.0	-4.0	-5.0
+America/Indiana/Knox	-6.0	-5.0	-6.0
+America/Indiana/Marengo	-5.0	-4.0	-5.0
+America/Indiana/Petersburg	-5.0	-4.0	-5.0
+America/Indiana/Tell_City	-6.0	-5.0	-6.0
+America/Indiana/Vevay	-5.0	-4.0	-5.0
+America/Indiana/Vincennes	-5.0	-4.0	-5.0
+America/Indiana/Winamac	-5.0	-4.0	-5.0
+America/Inuvik	-7.0	-6.0	-7.0
+America/Iqaluit	-5.0	-4.0	-5.0
+America/Jamaica	-5.0	-5.0	-5.0
+America/Juneau	-9.0	-8.0	-9.0
+America/Kentucky/Louisville	-5.0	-4.0	-5.0
+America/Kentucky/Monticello	-5.0	-4.0	-5.0
+America/La_Paz	-4.0	-4.0	-4.0
+America/Lima	-5.0	-5.0	-5.0
+America/Los_Angeles	-8.0	-7.0	-8.0
+America/Maceio	-3.0	-3.0	-3.0
+America/Managua	-6.0	-6.0	-6.0
+America/Manaus	-4.0	-4.0	-4.0
+America/Marigot	-4.0	-4.0	-4.0
+America/Martinique	-4.0	-4.0	-4.0
+America/Matamoros	-6.0	-5.0	-6.0
+America/Mazatlan	-7.0	-6.0	-7.0
+America/Menominee	-6.0	-5.0	-6.0
+America/Merida	-6.0	-5.0	-6.0
+America/Metlakatla	-8.0	-8.0	-8.0
+America/Mexico_City	-6.0	-5.0	-6.0
+America/Miquelon	-3.0	-2.0	-3.0
+America/Moncton	-4.0	-3.0	-4.0
+America/Monterrey	-6.0	-5.0	-6.0
+America/Montevideo	-2.0	-3.0	-3.0
+America/Montreal	-5.0	-4.0	-5.0
+America/Montserrat	-4.0	-4.0	-4.0
+America/Nassau	-5.0	-4.0	-5.0
+America/New_York	-5.0	-4.0	-5.0
+America/Nipigon	-5.0	-4.0	-5.0
+America/Nome	-9.0	-8.0	-9.0
+America/Noronha	-2.0	-2.0	-2.0
+America/North_Dakota/Beulah	-6.0	-5.0	-6.0
+America/North_Dakota/Center	-6.0	-5.0	-6.0
+America/North_Dakota/New_Salem	-6.0	-5.0	-6.0
+America/Ojinaga	-7.0	-6.0	-7.0
+America/Panama	-5.0	-5.0	-5.0
+America/Pangnirtung	-5.0	-4.0	-5.0
+America/Paramaribo	-3.0	-3.0	-3.0
+America/Phoenix	-7.0	-7.0	-7.0
+America/Port-au-Prince	-5.0	-5.0	-5.0
+America/Port_of_Spain	-4.0	-4.0	-4.0
+America/Porto_Velho	-4.0	-4.0	-4.0
+America/Puerto_Rico	-4.0	-4.0	-4.0
+America/Rainy_River	-6.0	-5.0	-6.0
+America/Rankin_Inlet	-6.0	-5.0	-6.0
+America/Recife	-3.0	-3.0	-3.0
+America/Regina	-6.0	-6.0	-6.0
+America/Resolute	-6.0	-5.0	-6.0
+America/Rio_Branco	-4.0	-4.0	-4.0
+America/Santa_Isabel	-8.0	-7.0	-8.0
+America/Santarem	-3.0	-3.0	-3.0
+America/Santiago	-3.0	-4.0	-4.0
+America/Santo_Domingo	-4.0	-4.0	-4.0
+America/Sao_Paulo	-2.0	-3.0	-3.0
+America/Scoresbysund	-1.0	0.0	-1.0
+America/Shiprock	-7.0	-6.0	-7.0
+America/Sitka	-9.0	-8.0	-9.0
+America/St_Barthelemy	-4.0	-4.0	-4.0
+America/St_Johns	-3.5	-2.5	-3.5
+America/St_Kitts	-4.0	-4.0	-4.0
+America/St_Lucia	-4.0	-4.0	-4.0
+America/St_Thomas	-4.0	-4.0	-4.0
+America/St_Vincent	-4.0	-4.0	-4.0
+America/Swift_Current	-6.0	-6.0	-6.0
+America/Tegucigalpa	-6.0	-6.0	-6.0
+America/Thule	-4.0	-3.0	-4.0
+America/Thunder_Bay	-5.0	-4.0	-5.0
+America/Tijuana	-8.0	-7.0	-8.0
+America/Toronto	-5.0	-4.0	-5.0
+America/Tortola	-4.0	-4.0	-4.0
+America/Vancouver	-8.0	-7.0	-8.0
+America/Whitehorse	-8.0	-7.0	-8.0
+America/Winnipeg	-6.0	-5.0	-6.0
+America/Yakutat	-9.0	-8.0	-9.0
+America/Yellowknife	-7.0	-6.0	-7.0
+Antarctica/Casey	8.0	8.0	8.0
+Antarctica/Davis	7.0	7.0	7.0
+Antarctica/DumontDUrville	10.0	10.0	10.0
+Antarctica/Macquarie	11.0	11.0	11.0
+Antarctica/Mawson	5.0	5.0	5.0
+Antarctica/McMurdo	13.0	12.0	12.0
+Antarctica/Palmer	-3.0	-4.0	-4.0
+Antarctica/Rothera	-3.0	-3.0	-3.0
+Antarctica/South_Pole	13.0	12.0	12.0
+Antarctica/Syowa	3.0	3.0	3.0
+Antarctica/Vostok	6.0	6.0	6.0
+Arctic/Longyearbyen	1.0	2.0	1.0
+Asia/Aden	3.0	3.0	3.0
+Asia/Almaty	6.0	6.0	6.0
+Asia/Amman	2.0	3.0	2.0
+Asia/Anadyr	11.0	12.0	12.0
+Asia/Aqtau	5.0	5.0	5.0
+Asia/Aqtobe	5.0	5.0	5.0
+Asia/Ashgabat	5.0	5.0	5.0
+Asia/Baghdad	3.0	3.0	3.0
+Asia/Bahrain	3.0	3.0	3.0
+Asia/Baku	4.0	5.0	4.0
+Asia/Bangkok	7.0	7.0	7.0
+Asia/Beirut	2.0	3.0	2.0
+Asia/Bishkek	6.0	6.0	6.0
+Asia/Brunei	8.0	8.0	8.0
+Asia/Choibalsan	8.0	8.0	8.0
+Asia/Chongqing	8.0	8.0	8.0
+Asia/Colombo	5.5	5.5	5.5
+Asia/Damascus	2.0	3.0	2.0
+Asia/Dhaka	6.0	6.0	6.0
+Asia/Dili	9.0	9.0	9.0
+Asia/Dubai	4.0	4.0	4.0
+Asia/Dushanbe	5.0	5.0	5.0
+Asia/Gaza	2.0	3.0	2.0
+Asia/Harbin	8.0	8.0	8.0
+Asia/Ho_Chi_Minh	7.0	7.0	7.0
+Asia/Hong_Kong	8.0	8.0	8.0
+Asia/Hovd	7.0	7.0	7.0
+Asia/Irkutsk	8.0	9.0	9.0
+Asia/Jakarta	7.0	7.0	7.0
+Asia/Jayapura	9.0	9.0	9.0
+Asia/Jerusalem	2.0	3.0	2.0
+Asia/Kabul	4.5	4.5	4.5
+Asia/Kamchatka	11.0	12.0	12.0
+Asia/Karachi	5.0	5.0	5.0
+Asia/Kashgar	8.0	8.0	8.0
+Asia/Kathmandu	5.75	5.75	5.75
+Asia/Kolkata	5.5	5.5	5.5
+Asia/Krasnoyarsk	7.0	8.0	8.0
+Asia/Kuala_Lumpur	8.0	8.0	8.0
+Asia/Kuching	8.0	8.0	8.0
+Asia/Kuwait	3.0	3.0	3.0
+Asia/Macau	8.0	8.0	8.0
+Asia/Magadan	11.0	12.0	12.0
+Asia/Makassar	8.0	8.0	8.0
+Asia/Manila	8.0	8.0	8.0
+Asia/Muscat	4.0	4.0	4.0
+Asia/Nicosia	2.0	3.0	2.0
+Asia/Novokuznetsk	6.0	7.0	7.0
+Asia/Novosibirsk	6.0	7.0	7.0
+Asia/Omsk	6.0	7.0	7.0
+Asia/Oral	5.0	5.0	5.0
+Asia/Phnom_Penh	7.0	7.0	7.0
+Asia/Pontianak	7.0	7.0	7.0
+Asia/Pyongyang	9.0	9.0	9.0
+Asia/Qatar	3.0	3.0	3.0
+Asia/Qyzylorda	6.0	6.0	6.0
+Asia/Rangoon	6.5	6.5	6.5
+Asia/Riyadh	3.0	3.0	3.0
+Asia/Sakhalin	10.0	11.0	11.0
+Asia/Samarkand	5.0	5.0	5.0
+Asia/Seoul	9.0	9.0	9.0
+Asia/Shanghai	8.0	8.0	8.0
+Asia/Singapore	8.0	8.0	8.0
+Asia/Taipei	8.0	8.0	8.0
+Asia/Tashkent	5.0	5.0	5.0
+Asia/Tbilisi	4.0	4.0	4.0
+Asia/Tehran	3.5	4.5	3.5
+Asia/Thimphu	6.0	6.0	6.0
+Asia/Tokyo	9.0	9.0	9.0
+Asia/Ulaanbaatar	8.0	8.0	8.0
+Asia/Urumqi	8.0	8.0	8.0
+Asia/Vientiane	7.0	7.0	7.0
+Asia/Vladivostok	10.0	11.0	11.0
+Asia/Yakutsk	9.0	10.0	10.0
+Asia/Yekaterinburg	5.0	6.0	6.0
+Asia/Yerevan	4.0	5.0	4.0
+Atlantic/Azores	-1.0	0.0	-1.0
+Atlantic/Bermuda	-4.0	-3.0	-4.0
+Atlantic/Canary	0.0	1.0	0.0
+Atlantic/Cape_Verde	-1.0	-1.0	-1.0
+Atlantic/Faroe	0.0	1.0	0.0
+Atlantic/Madeira	0.0	1.0	0.0
+Atlantic/Reykjavik	0.0	0.0	0.0
+Atlantic/South_Georgia	-2.0	-2.0	-2.0
+Atlantic/St_Helena	0.0	0.0	0.0
+Atlantic/Stanley	-3.0	-3.0	-4.0
+Australia/Adelaide	10.5	9.5	9.5
+Australia/Brisbane	10.0	10.0	10.0
+Australia/Broken_Hill	10.5	9.5	9.5
+Australia/Currie	11.0	10.0	10.0
+Australia/Darwin	9.5	9.5	9.5
+Australia/Eucla	8.75	8.75	8.75
+Australia/Hobart	11.0	10.0	10.0
+Australia/Lindeman	10.0	10.0	10.0
+Australia/Lord_Howe	11.0	10.5	10.5
+Australia/Melbourne	11.0	10.0	10.0
+Australia/Perth	8.0	8.0	8.0
+Australia/Sydney	11.0	10.0	10.0
+Europe/Amsterdam	1.0	2.0	1.0
+Europe/Andorra	1.0	2.0	1.0
+Europe/Athens	2.0	3.0	2.0
+Europe/Belgrade	1.0	2.0	1.0
+Europe/Berlin	1.0	2.0	1.0
+Europe/Bratislava	1.0	2.0	1.0
+Europe/Brussels	1.0	2.0	1.0
+Europe/Bucharest	2.0	3.0	2.0
+Europe/Budapest	1.0	2.0	1.0
+Europe/Chisinau	2.0	3.0	2.0
+Europe/Copenhagen	1.0	2.0	1.0
+Europe/Dublin	0.0	1.0	0.0
+Europe/Gibraltar	1.0	2.0	1.0
+Europe/Guernsey	0.0	1.0	0.0
+Europe/Helsinki	2.0	3.0	2.0
+Europe/Isle_of_Man	0.0	1.0	0.0
+Europe/Istanbul	2.0	3.0	2.0
+Europe/Jersey	0.0	1.0	0.0
+Europe/Kaliningrad	2.0	3.0	3.0
+Europe/Kiev	2.0	3.0	3.0
+Europe/Lisbon	0.0	1.0	0.0
+Europe/Ljubljana	1.0	2.0	1.0
+Europe/London	0.0	1.0	0.0
+Europe/Luxembourg	1.0	2.0	1.0
+Europe/Madrid	1.0	2.0	1.0
+Europe/Malta	1.0	2.0	1.0
+Europe/Mariehamn	2.0	3.0	2.0
+Europe/Minsk	2.0	3.0	3.0
+Europe/Monaco	1.0	2.0	1.0
+Europe/Moscow	3.0	4.0	4.0
+Europe/Oslo	1.0	2.0	1.0
+Europe/Paris	1.0	2.0	1.0
+Europe/Podgorica	1.0	2.0	1.0
+Europe/Prague	1.0	2.0	1.0
+Europe/Riga	2.0	3.0	2.0
+Europe/Rome	1.0	2.0	1.0
+Europe/Samara	3.0	4.0	4.0
+Europe/San_Marino	1.0	2.0	1.0
+Europe/Sarajevo	1.0	2.0	1.0
+Europe/Simferopol	2.0	3.0	3.0
+Europe/Skopje	1.0	2.0	1.0
+Europe/Sofia	2.0	3.0	2.0
+Europe/Stockholm	1.0	2.0	1.0
+Europe/Tallinn	2.0	3.0	2.0
+Europe/Tirane	1.0	2.0	1.0
+Europe/Uzhgorod	2.0	3.0	3.0
+Europe/Vaduz	1.0	2.0	1.0
+Europe/Vatican	1.0	2.0	1.0
+Europe/Vienna	1.0	2.0	1.0
+Europe/Vilnius	2.0	3.0	2.0
+Europe/Volgograd	3.0	4.0	4.0
+Europe/Warsaw	1.0	2.0	1.0
+Europe/Zagreb	1.0	2.0	1.0
+Europe/Zaporozhye	2.0	3.0	3.0
+Europe/Zurich	1.0	2.0	1.0
+Indian/Antananarivo	3.0	3.0	3.0
+Indian/Chagos	6.0	6.0	6.0
+Indian/Christmas	7.0	7.0	7.0
+Indian/Cocos	6.5	6.5	6.5
+Indian/Comoro	3.0	3.0	3.0
+Indian/Kerguelen	5.0	5.0	5.0
+Indian/Mahe	4.0	4.0	4.0
+Indian/Maldives	5.0	5.0	5.0
+Indian/Mauritius	4.0	4.0	4.0
+Indian/Mayotte	3.0	3.0	3.0
+Indian/Reunion	4.0	4.0	4.0
+Pacific/Apia	-10.0	-11.0	-11.0
+Pacific/Auckland	13.0	12.0	12.0
+Pacific/Chatham	13.75	12.75	12.75
+Pacific/Chuuk	10.0	10.0	10.0
+Pacific/Easter	-5.0	-6.0	-6.0
+Pacific/Efate	11.0	11.0	11.0
+Pacific/Enderbury	13.0	13.0	13.0
+Pacific/Fakaofo	-10.0	-10.0	-10.0
+Pacific/Fiji	13.0	12.0	12.0
+Pacific/Funafuti	12.0	12.0	12.0
+Pacific/Galapagos	-6.0	-6.0	-6.0
+Pacific/Gambier	-9.0	-9.0	-9.0
+Pacific/Guadalcanal	11.0	11.0	11.0
+Pacific/Guam	10.0	10.0	10.0
+Pacific/Honolulu	-10.0	-10.0	-10.0
+Pacific/Johnston	-10.0	-10.0	-10.0
+Pacific/Kiritimati	14.0	14.0	14.0
+Pacific/Kosrae	11.0	11.0	11.0
+Pacific/Kwajalein	12.0	12.0	12.0
+Pacific/Majuro	12.0	12.0	12.0
+Pacific/Marquesas	-9.5	-9.5	-9.5
+Pacific/Midway	-11.0	-11.0	-11.0
+Pacific/Nauru	12.0	12.0	12.0
+Pacific/Niue	-11.0	-11.0	-11.0
+Pacific/Norfolk	11.5	11.5	11.5
+Pacific/Noumea	11.0	11.0	11.0
+Pacific/Pago_Pago	-11.0	-11.0	-11.0
+Pacific/Palau	9.0	9.0	9.0
+Pacific/Pitcairn	-8.0	-8.0	-8.0
+Pacific/Pohnpei	11.0	11.0	11.0
+Pacific/Port_Moresby	10.0	10.0	10.0
+Pacific/Rarotonga	-10.0	-10.0	-10.0
+Pacific/Saipan	10.0	10.0	10.0
+Pacific/Tahiti	-10.0	-10.0	-10.0
+Pacific/Tarawa	12.0	12.0	12.0
+Pacific/Tongatapu	13.0	13.0	13.0
+Pacific/Wake	12.0	12.0	12.0
+Pacific/Wallis	12.0	12.0	12.0
--- a/dataimport/test/test_csv.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/dataimport/test/test_csv.py	Thu Dec 10 12:34:15 2015 +0100
@@ -17,7 +17,7 @@
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """unittest for cubicweb.dataimport.csv"""
 
-from StringIO import StringIO
+from io import BytesIO
 
 from logilab.common.testlib import TestCase, unittest_main
 
@@ -27,7 +27,7 @@
 class UcsvreaderTC(TestCase):
 
     def test_empty_lines_skipped(self):
-        stream = StringIO('''a,b,c,d,
+        stream = BytesIO(b'''a,b,c,d,
 1,2,3,4,
 ,,,,
 ,,,,
@@ -45,7 +45,7 @@
                          list(csv.ucsvreader(stream, skip_empty=False)))
 
     def test_skip_first(self):
-        stream = StringIO('a,b,c,d,\n1,2,3,4,\n')
+        stream = BytesIO(b'a,b,c,d,\n1,2,3,4,\n')
         reader = csv.ucsvreader(stream, skipfirst=True, ignore_errors=True)
         self.assertEqual(list(reader),
                          [[u'1', u'2', u'3', u'4', u'']])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dataimport/test/test_massive_store.py	Thu Dec 10 12:34:15 2015 +0100
@@ -0,0 +1,263 @@
+# -*- coding: utf-8 -*-
+# copyright 2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# contact http://www.logilab.fr -- mailto:contact@logilab.fr
+#
+# This program 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 2.1 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 Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+"""Massive store test case"""
+
+import itertools
+
+from cubicweb.dataimport import ucsvreader
+from cubicweb.devtools import testlib, PostgresApptestConfiguration
+from cubicweb.devtools import startpgcluster, stoppgcluster
+from cubicweb.dataimport.massive_store import MassiveObjectStore
+
+
+def setUpModule():
+    startpgcluster(__file__)
+
+
+def tearDownModule(*args):
+    stoppgcluster(__file__)
+
+
+class MassImportSimpleTC(testlib.CubicWebTC):
+    configcls = PostgresApptestConfiguration
+    appid = 'data-massimport'
+
+    def cast(self, _type, value):
+        try:
+            return _type(value)
+        except ValueError:
+            return None
+
+    def push_geonames_data(self, dumpname, store):
+        # Push timezones
+        cnx = store._cnx
+        for code, gmt, dst, raw_offset in ucsvreader(open(self.datapath('timeZones.txt'), 'rb'),
+                                                     delimiter='\t'):
+            cnx.create_entity('TimeZone', code=code, gmt=float(gmt),
+                                    dst=float(dst), raw_offset=float(raw_offset))
+        timezone_code = dict(cnx.execute('Any C, X WHERE X is TimeZone, X code C'))
+        # Push data
+        for ind, infos in enumerate(ucsvreader(open(dumpname, 'rb'),
+                                               delimiter='\t',
+                                               ignore_errors=True)):
+            latitude = self.cast(float, infos[4])
+            longitude = self.cast(float, infos[5])
+            population = self.cast(int, infos[14])
+            elevation = self.cast(int, infos[15])
+            gtopo = self.cast(int, infos[16])
+            feature_class = infos[6]
+            if len(infos[6]) != 1:
+                feature_class = None
+            entity = {'name': infos[1],
+                      'asciiname': infos[2],
+                      'alternatenames': infos[3],
+                      'latitude': latitude, 'longitude': longitude,
+                      'feature_class': feature_class,
+                      'alternate_country_code':infos[9],
+                      'admin_code_3': infos[12],
+                      'admin_code_4': infos[13],
+                      'population': population, 'elevation': elevation,
+                      'gtopo30': gtopo, 'timezone': timezone_code.get(infos[17]),
+                      'cwuri':  u'http://sws.geonames.org/%s/' % int(infos[0]),
+                      'geonameid': int(infos[0]),
+                      }
+            store.prepare_insert_entity('Location', **entity)
+
+    def test_autoflush_metadata(self):
+        with self.admin_access.repo_cnx() as cnx:
+            crs = cnx.system_sql('SELECT * FROM entities WHERE type=%(t)s',
+                                 {'t': 'Location'})
+            self.assertEqual(len(crs.fetchall()), 0)
+            store = MassiveObjectStore(cnx)
+            store.prepare_insert_entity('Location', name=u'toto')
+            store.flush()
+            store.commit()
+            store.finish()
+            cnx.commit()
+        with self.admin_access.repo_cnx() as cnx:
+            crs = cnx.system_sql('SELECT * FROM entities WHERE type=%(t)s',
+                                 {'t': 'Location'})
+            self.assertEqual(len(crs.fetchall()), 1)
+
+    def test_massimport_etype_metadata(self):
+        with self.admin_access.repo_cnx() as cnx:
+            store = MassiveObjectStore(cnx)
+            timezone_eid = store.prepare_insert_entity('TimeZone')
+            store.prepare_insert_entity('Location', timezone=timezone_eid)
+            store.flush()
+            store.commit()
+            eid, etname = cnx.execute('Any X, TN WHERE X timezone TZ, X is T, '
+                                      'T name TN')[0]
+            self.assertEqual(cnx.entity_from_eid(eid).cw_etype, etname)
+
+    def test_drop_index(self):
+        with self.admin_access.repo_cnx() as cnx:
+            store = MassiveObjectStore(cnx)
+            cnx.commit()
+        with self.admin_access.repo_cnx() as cnx:
+            crs = cnx.system_sql('SELECT indexname FROM pg_indexes')
+            indexes = [r[0] for r in crs.fetchall()]
+        self.assertNotIn('entities_pkey', indexes)
+        self.assertNotIn('unique_entities_extid_idx', indexes)
+        self.assertNotIn('owned_by_relation_pkey', indexes)
+        self.assertNotIn('owned_by_relation_to_idx', indexes)
+
+    def test_drop_index_recreation(self):
+        with self.admin_access.repo_cnx() as cnx:
+            store = MassiveObjectStore(cnx)
+            store.finish()
+            cnx.commit()
+        with self.admin_access.repo_cnx() as cnx:
+            crs = cnx.system_sql('SELECT indexname FROM pg_indexes')
+            indexes = [r[0] for r in crs.fetchall()]
+        self.assertIn('entities_pkey', indexes)
+        self.assertIn('unique_entities_extid_idx', indexes)
+        self.assertIn('owned_by_relation_p_key', indexes)
+        self.assertIn('owned_by_relation_to_idx', indexes)
+
+    def test_eids_seq_range(self):
+        class MyMassiveObjectStore(MassiveObjectStore):
+            eids_seq_range = 1000
+            eids_seq_start = 50000
+
+        with self.admin_access.repo_cnx() as cnx:
+            store = MyMassiveObjectStore(cnx)
+            store.prepare_insert_entity('Location', name=u'toto')
+            store.flush()
+            cnx.commit()
+        with self.admin_access.repo_cnx() as cnx:
+            crs = cnx.system_sql("SELECT * FROM entities_id_seq")
+            self.assertGreater(crs.fetchone()[0], 50000)
+
+    def test_eid_entity(self):
+        class MyMassiveObjectStore(MassiveObjectStore):
+            eids_seq_range = 1000
+            eids_seq_start = 50000
+
+        with self.admin_access.repo_cnx() as cnx:
+            store = MyMassiveObjectStore(cnx)
+            eid = store.prepare_insert_entity('Location', name=u'toto')
+            store.flush()
+            self.assertGreater(eid, 50000)
+
+    def test_eid_entity_2(self):
+        class MyMassiveObjectStore(MassiveObjectStore):
+            eids_seq_range = 1000
+            eids_seq_start = 50000
+
+        with self.admin_access.repo_cnx() as cnx:
+            store = MyMassiveObjectStore(cnx)
+            eid = store.prepare_insert_entity('Location', name=u'toto', eid=10000)
+            store.flush()
+        self.assertEqual(eid, 10000)
+
+    def test_on_commit_callback(self):
+        counter = itertools.count()
+        with self.admin_access.repo_cnx() as cnx:
+            store = MassiveObjectStore(cnx, on_commit_callback=lambda:next(counter))
+            store.prepare_insert_entity('Location', name=u'toto')
+            store.flush()
+            store.commit()
+        self.assertGreaterEqual(next(counter), 1)
+
+    def test_on_rollback_callback(self):
+        counter = itertools.count()
+        with self.admin_access.repo_cnx() as cnx:
+            store = MassiveObjectStore(cnx, on_rollback_callback=lambda *_: next(counter))
+            store.prepare_insert_entity('Location', nm='toto')
+            store.flush()
+            store.commit()
+        self.assertGreaterEqual(next(counter), 1)
+
+    def test_slave_mode_indexes(self):
+        with self.admin_access.repo_cnx() as cnx:
+            slave_store = MassiveObjectStore(cnx, slave_mode=True)
+        with self.admin_access.repo_cnx() as cnx:
+            crs = cnx.system_sql('SELECT indexname FROM pg_indexes')
+            indexes = [r[0] for r in crs.fetchall()]
+        self.assertIn('entities_pkey', indexes)
+        self.assertIn('unique_entities_extid_idx', indexes)
+        self.assertIn('owned_by_relation_p_key', indexes)
+        self.assertIn('owned_by_relation_to_idx', indexes)
+
+    def test_slave_mode_exception(self):
+        with self.admin_access.repo_cnx() as cnx:
+            master_store = MassiveObjectStore(cnx, slave_mode=False)
+            slave_store = MassiveObjectStore(cnx, slave_mode=True)
+            self.assertRaises(RuntimeError, slave_store.flush_meta_data)
+            self.assertRaises(RuntimeError, slave_store.finish)
+
+    def test_simple_insert(self):
+        with self.admin_access.repo_cnx() as cnx:
+            store = MassiveObjectStore(cnx)
+            self.push_geonames_data(self.datapath('geonames.csv'), store)
+            store.flush()
+            store.commit()
+            store.finish()
+        with self.admin_access.repo_cnx() as cnx:
+            rset = cnx.execute('Any X WHERE X is Location')
+            self.assertEqual(len(rset), 4000)
+            rset = cnx.execute('Any X WHERE X is Location, X timezone T')
+            self.assertEqual(len(rset), 4000)
+
+    def test_index_building(self):
+        with self.admin_access.repo_cnx() as cnx:
+            store = MassiveObjectStore(cnx)
+            self.push_geonames_data(self.datapath('geonames.csv'), store)
+            store.flush()
+
+            # Check index
+            crs = cnx.system_sql('SELECT indexname FROM pg_indexes')
+            indexes = [r[0] for r in crs.fetchall()]
+            self.assertNotIn('entities_pkey', indexes)
+            self.assertNotIn('unique_entities_extid_idx', indexes)
+            self.assertNotIn('owned_by_relation_p_key', indexes)
+            self.assertNotIn('owned_by_relation_to_idx', indexes)
+
+            # Cleanup -> index
+            store.finish()
+
+            # Check index again
+            crs = cnx.system_sql('SELECT indexname FROM pg_indexes')
+            indexes = [r[0] for r in crs.fetchall()]
+            self.assertIn('entities_pkey', indexes)
+            self.assertIn('unique_entities_extid_idx', indexes)
+            self.assertIn('owned_by_relation_p_key', indexes)
+            self.assertIn('owned_by_relation_to_idx', indexes)
+
+    def test_multiple_insert(self):
+        with self.admin_access.repo_cnx() as cnx:
+            store = MassiveObjectStore(cnx)
+            store.init_etype_table('TestLocation')
+            store.finish()
+            store = MassiveObjectStore(cnx)
+            store.init_etype_table('TestLocation')
+            store.finish()
+
+    def test_multiple_insert_relation(self):
+        with self.admin_access.repo_cnx() as cnx:
+            store = MassiveObjectStore(cnx)
+            store.init_relation_table('used_language')
+            store.finish()
+            store = MassiveObjectStore(cnx)
+            store.init_relation_table('used_language')
+            store.finish()
+
+
+if __name__ == '__main__':
+    from logilab.common.testlib import unittest_main
+    unittest_main()
--- a/dataimport/test/test_pgstore.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/dataimport/test/test_pgstore.py	Thu Dec 10 12:34:15 2015 +0100
@@ -20,9 +20,11 @@
 
 import datetime as DT
 
+from six import PY2
 from logilab.common.testlib import TestCase, unittest_main
 
 from cubicweb.dataimport import pgstore
+from cubicweb.devtools import testlib
 
 
 class CreateCopyFromBufferTC(TestCase):
@@ -31,24 +33,24 @@
 
     def test_convert_none(self):
         cnvt = pgstore._copyfrom_buffer_convert_None
-        self.assertEqual('NULL', cnvt(None))
+        self.assertEqual(u'NULL', cnvt(None))
 
     def test_convert_number(self):
         cnvt = pgstore._copyfrom_buffer_convert_number
-        self.assertEqual('42', cnvt(42))
-        self.assertEqual('42', cnvt(42L))
-        self.assertEqual('42.42', cnvt(42.42))
+        self.assertEqual(u'42', cnvt(42))
+        if PY2:
+            self.assertEqual(u'42', cnvt(long(42)))
+        self.assertEqual(u'42.42', cnvt(42.42))
 
     def test_convert_string(self):
         cnvt = pgstore._copyfrom_buffer_convert_string
         # simple
-        self.assertEqual('babar', cnvt('babar'))
+        self.assertEqual(u'babar', cnvt('babar'))
         # unicode
-        self.assertEqual('\xc3\xa9l\xc3\xa9phant', cnvt(u'éléphant'))
-        self.assertEqual('\xe9l\xe9phant', cnvt(u'éléphant', encoding='latin1'))
+        self.assertEqual(u'éléphant', cnvt(u'éléphant'))
         # escaping
-        self.assertEqual('babar\\tceleste\\n', cnvt('babar\tceleste\n'))
-        self.assertEqual(r'C:\\new\tC:\\test', cnvt('C:\\new\tC:\\test'))
+        self.assertEqual(u'babar\\tceleste\\n', cnvt(u'babar\tceleste\n'))
+        self.assertEqual(u'C:\\\\new\\tC:\\\\test', cnvt(u'C:\\new\tC:\\test'))
 
     def test_convert_date(self):
         cnvt = pgstore._copyfrom_buffer_convert_date
@@ -64,18 +66,19 @@
 
     # test buffer
     def test_create_copyfrom_buffer_tuple(self):
-        data = ((42, 42L, 42.42, u'éléphant', DT.date(666, 1, 13), DT.time(6, 6, 6),
+        l = long if PY2 else int
+        data = ((42, l(42), 42.42, u'éléphant', DT.date(666, 1, 13), DT.time(6, 6, 6),
                  DT.datetime(666, 6, 13, 6, 6, 6)),
-                (6, 6L, 6.6, u'babar', DT.date(2014, 1, 14), DT.time(4, 2, 1),
+                (6, l(6), 6.6, u'babar', DT.date(2014, 1, 14), DT.time(4, 2, 1),
                  DT.datetime(2014, 1, 1, 0, 0, 0)))
         results = pgstore._create_copyfrom_buffer(data)
         # all columns
-        expected = '''42\t42\t42.42\téléphant\t0666-01-13\t06:06:06.000000\t0666-06-13 06:06:06.000000
+        expected = u'''42\t42\t42.42\téléphant\t0666-01-13\t06:06:06.000000\t0666-06-13 06:06:06.000000
 6\t6\t6.6\tbabar\t2014-01-14\t04:02:01.000000\t2014-01-01 00:00:00.000000'''
         self.assertMultiLineEqual(expected, results.getvalue())
         # selected columns
         results = pgstore._create_copyfrom_buffer(data, columns=(1, 3, 6))
-        expected = '''42\téléphant\t0666-06-13 06:06:06.000000
+        expected = u'''42\téléphant\t0666-06-13 06:06:06.000000
 6\tbabar\t2014-01-01 00:00:00.000000'''
         self.assertMultiLineEqual(expected, results.getvalue())
 
@@ -85,8 +88,19 @@
                 dict(integer=6, double=6.6, text=u'babar',
                      date=DT.datetime(2014, 1, 1, 0, 0, 0)))
         results = pgstore._create_copyfrom_buffer(data, ('integer', 'text'))
-        expected = '''42\téléphant\n6\tbabar'''
-        self.assertMultiLineEqual(expected, results.getvalue())
+        expected = u'''42\téléphant\n6\tbabar'''
+        self.assertEqual(expected, results.getvalue())
+
+
+class SQLGenObjectStoreTC(testlib.CubicWebTC):
+
+    def test_prepare_insert_entity(self):
+        with self.admin_access.repo_cnx() as cnx:
+            store = pgstore.SQLGenObjectStore(cnx)
+            eid = store.prepare_insert_entity('CWUser', login=u'toto',
+                                              upassword=u'pwd')
+            self.assertIsNotNone(eid)
+
 
 if __name__ == '__main__':
     unittest_main()
--- a/dataimport/test/unittest_importer.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/dataimport/test/unittest_importer.py	Thu Dec 10 12:34:15 2015 +0100
@@ -152,14 +152,14 @@
 class UseExtidAsCwuriTC(TestCase):
 
     def test(self):
-        personne = ExtEntity('Personne', 1, {'nom': set([u'de la lune']),
-                                             'prenom': set([u'Jean'])})
+        personne = ExtEntity('Personne', b'1', {'nom': set([u'de la lune']),
+                                                'prenom': set([u'Jean'])})
         mapping = {}
         set_cwuri = use_extid_as_cwuri(mapping)
         list(set_cwuri((personne,)))
         self.assertIn('cwuri', personne.values)
-        self.assertEqual(personne.values['cwuri'], set(['1']))
-        mapping[1] = 'whatever'
+        self.assertEqual(personne.values['cwuri'], set([u'1']))
+        mapping[b'1'] = 'whatever'
         personne.values.pop('cwuri')
         list(set_cwuri((personne,)))
         self.assertNotIn('cwuri', personne.values)
@@ -167,7 +167,7 @@
 
 def extentities_from_csv(fpath):
     """Yield ExtEntity read from `fpath` CSV file."""
-    with open(fpath) as f:
+    with open(fpath, 'rb') as f:
         for uri, name, knows in ucsvreader(f, skipfirst=True, skip_empty=False):
             yield ExtEntity('Personne', uri,
                             {'nom': set([name]), 'connait': set([knows])})
--- a/debian/control	Wed Dec 09 18:42:13 2015 +0100
+++ b/debian/control	Thu Dec 10 12:34:15 2015 +0100
@@ -10,13 +10,14 @@
 Build-Depends:
  debhelper (>= 7),
  python (>= 2.6),
+ python-six (>= 1.4.0),
  python-sphinx,
  python-logilab-common,
  python-unittest2 | python (>= 2.7),
  python-logilab-mtconverter,
  python-markdown,
  python-rql,
- python-yams (>= 0.40.0),
+ python-yams (>= 0.41.1),
  python-lxml,
 Standards-Version: 3.9.1
 Homepage: http://www.cubicweb.org
@@ -155,10 +156,11 @@
  ${python:Depends},
  graphviz,
  gettext,
+ python-six (>= 1.4.0),
  python-logilab-mtconverter (>= 0.8.0),
  python-logilab-common (>= 0.63.1),
  python-markdown,
- python-yams (>= 0.40.0),
+ python-yams (>= 0.41.1)
  python-rql (>= 0.31.2),
  python-lxml
 Recommends:
--- a/devtools/__init__.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/devtools/__init__.py	Thu Dec 10 12:34:15 2015 +0100
@@ -16,6 +16,7 @@
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """Test tools for cubicweb"""
+from __future__ import print_function
 
 __docformat__ = "restructuredtext en"
 
@@ -24,7 +25,6 @@
 import errno
 import logging
 import shutil
-import pickle
 import glob
 import subprocess
 import warnings
@@ -35,6 +35,9 @@
 from os.path import (abspath, realpath, join, exists, split, isabs, isdir)
 from functools import partial
 
+from six import text_type
+from six.moves import cPickle as pickle
+
 from logilab.common.date import strptime
 from logilab.common.decorators import cached, clear_cache
 
@@ -92,7 +95,7 @@
 DEFAULT_PSQL_SOURCES = DEFAULT_SOURCES.copy()
 DEFAULT_PSQL_SOURCES['system'] = DEFAULT_SOURCES['system'].copy()
 DEFAULT_PSQL_SOURCES['system']['db-driver'] = 'postgres'
-DEFAULT_PSQL_SOURCES['system']['db-user'] = unicode(getpass.getuser())
+DEFAULT_PSQL_SOURCES['system']['db-user'] = text_type(getpass.getuser())
 DEFAULT_PSQL_SOURCES['system']['db-password'] = None
 
 def turn_repo_off(repo):
@@ -109,7 +112,7 @@
             try:
                 repo.close(sessionid)
             except BadConnectionId: #this is strange ? thread issue ?
-                print 'XXX unknown session', sessionid
+                print('XXX unknown session', sessionid)
         for cnxset in repo.cnxsets:
             cnxset.close(True)
         repo.system_source.shutdown()
@@ -162,7 +165,7 @@
             return None, None
         return self.anonymous_credential
 
-    def set_anonymous_allowed(self, allowed, anonuser='anon'):
+    def set_anonymous_allowed(self, allowed, anonuser=u'anon'):
         if allowed:
             self.anonymous_credential = (anonuser, anonuser)
         else:
@@ -193,7 +196,7 @@
     def sources_file(self):
         """define in subclasses self.sourcefile if necessary"""
         if self.sourcefile:
-            print 'Reading sources from', self.sourcefile
+            print('Reading sources from', self.sourcefile)
             sourcefile = self.sourcefile
             if not isabs(sourcefile):
                 sourcefile = join(self.apphome, sourcefile)
@@ -367,7 +370,8 @@
         # XXX set a clearer error message ???
         backup_coordinates, config_path = self.db_cache[self.db_cache_key(db_id)]
         # reload the config used to create the database.
-        config = pickle.loads(open(config_path, 'rb').read())
+        with open(config_path, 'rb') as f:
+            config = pickle.load(f)
         # shutdown repo before changing database content
         if self._repo is not None:
             self._repo.turn_repo_off()
@@ -399,9 +403,8 @@
 
     def _new_repo(self, config):
         """Factory method to create a new Repository Instance"""
-        from cubicweb.repoapi import _get_inmemory_repo
         config._cubes = None
-        repo = _get_inmemory_repo(config)
+        repo = config.repository()
         config.repository = lambda x=None: repo
         # extending Repository class
         repo._has_started = False
@@ -415,7 +418,7 @@
         from cubicweb.repoapi import connect
         repo = self.get_repo()
         sources = self.config.read_sources_file()
-        login  = unicode(sources['admin']['login'])
+        login  = text_type(sources['admin']['login'])
         password = sources['admin']['password'] or 'xxx'
         cnx = connect(repo, login, password=password)
         return cnx
@@ -464,7 +467,7 @@
             dbname, data = data.split('-', 1)
             db_id, filetype = data.split('.', 1)
             entries.setdefault((dbname, db_id), {})[filetype] = filepath
-        for (dbname, db_id), entry in entries.iteritems():
+        for (dbname, db_id), entry in entries.items():
             # apply necessary transformation from the driver
             value = self.process_cache_entry(directory, dbname, db_id, entry)
             assert 'config' in entry
@@ -494,7 +497,7 @@
         if test_db_id is DEFAULT_EMPTY_DB_ID:
             self.init_test_database()
         else:
-            print 'Building %s for database %s' % (test_db_id, self.dbname)
+            print('Building %s for database %s' % (test_db_id, self.dbname))
             self.build_db_cache(DEFAULT_EMPTY_DB_ID)
             self.restore_database(DEFAULT_EMPTY_DB_ID)
             repo = self.get_repo(startup=True)
@@ -543,7 +546,7 @@
         try:
             subprocess.check_call(['initdb', '-D', datadir, '-E', 'utf-8', '--locale=C'])
 
-        except OSError, err:
+        except OSError as err:
             if err.errno == errno.ENOENT:
                 raise OSError('"initdb" could not be found. '
                               'You should add the postgresql bin folder to your PATH '
@@ -562,7 +565,11 @@
         subprocess.check_call(['pg_ctl', 'start', '-w', '-D', datadir,
                                '-o', options],
                               env=env)
-    except OSError, err:
+    except OSError as err:
+        try:
+            os.rmdir(sockdir)
+        except OSError:
+            pass
         if err.errno == errno.ENOENT:
             raise OSError('"pg_ctl" could not be found. '
                           'You should add the postgresql bin folder to your PATH '
@@ -575,6 +582,10 @@
     datadir = join(os.path.dirname(pyfile), 'data',
                    'pgdb-%s' % os.path.splitext(os.path.basename(pyfile))[0])
     subprocess.call(['pg_ctl', 'stop', '-D', datadir, '-m', 'fast'])
+    try:
+        os.rmdir(DEFAULT_PSQL_SOURCES['system']['db-host'])
+    except OSError:
+        pass
 
 
 class PostgresTestDataBaseHandler(TestDataBaseHandler):
@@ -678,7 +689,7 @@
 
     @property
     def _config_id(self):
-        return sha1(self.config.apphome).hexdigest()[:10]
+        return sha1(self.config.apphome.encode('utf-8')).hexdigest()[:10]
 
     def _backup_name(self, db_id): # merge me with parent
         backup_name = '_'.join(('cache', self._config_id, self.dbname, db_id))
@@ -834,21 +845,21 @@
                 found_date = False
                 for row, rowdesc in zip(rset, rset.description):
                     for cellindex, (value, vtype) in enumerate(zip(row, rowdesc)):
-                        if vtype in ('Date', 'Datetime') and type(value) is unicode:
+                        if vtype in ('Date', 'Datetime') and isinstance(value, text_type):
                             found_date = True
                             value = value.rsplit('.', 1)[0]
                             try:
                                 row[cellindex] = strptime(value, '%Y-%m-%d %H:%M:%S')
                             except Exception:
                                 row[cellindex] = strptime(value, '%Y-%m-%d')
-                        if vtype == 'Time' and type(value) is unicode:
+                        if vtype == 'Time' and isinstance(value, text_type):
                             found_date = True
                             try:
                                 row[cellindex] = strptime(value, '%H:%M:%S')
                             except Exception:
                                 # DateTime used as Time?
                                 row[cellindex] = strptime(value, '%Y-%m-%d %H:%M:%S')
-                        if vtype == 'Interval' and type(value) is int:
+                        if vtype == 'Interval' and isinstance(value, int):
                             found_date = True
                             row[cellindex] = timedelta(0, value, 0) # XXX value is in number of seconds?
                     if not found_date:
@@ -882,7 +893,7 @@
     We only keep one repo in cache to prevent too much objects to stay alive
     (database handler holds a reference to a repository). As at the moment a new
     handler is created for each TestCase class and all test methods are executed
-    sequentialy whithin this class, there should not have more cache miss that
+    sequentially whithin this class, there should not have more cache miss that
     if we had a wider cache as once a Handler stop being used it won't be used
     again.
     """
@@ -947,5 +958,3 @@
     handler = get_test_db_handler(config)
     handler.build_db_cache()
     return handler.get_repo_and_cnx()
-
-
--- a/devtools/devctl.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/devtools/devctl.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,6 +18,7 @@
 """additional cubicweb-ctl commands and command handlers for cubicweb and
 cubicweb's cubes development
 """
+from __future__ import print_function
 
 __docformat__ = "restructuredtext en"
 
@@ -83,7 +84,7 @@
 
 def cleanup_sys_modules(config):
     # cleanup sys.modules, required when we're updating multiple cubes
-    for name, mod in sys.modules.items():
+    for name, mod in list(sys.modules.items()):
         if mod is None:
             # duh ? logilab.common.os for instance
             del sys.modules[name]
@@ -250,7 +251,7 @@
                 # bw compat, necessary until all translation of relation are
                 # done properly...
                 add_msg(w, '%s_object' % rtype)
-        for rdef in rschema.rdefs.itervalues():
+        for rdef in rschema.rdefs.values():
             if not rdef.description or rdef.description in done:
                 continue
             if (librschema is None or
@@ -267,7 +268,7 @@
     for reg, objdict in vreg.items():
         if reg in ('boxes', 'contentnavigation'):
             continue
-        for objects in objdict.itervalues():
+        for objects in objdict.values():
             for obj in objects:
                 objid = '%s_%s' % (reg, obj.__regid__)
                 if objid in done:
@@ -314,21 +315,21 @@
         from cubicweb.i18n import extract_from_tal, execute2
         tempdir = tempfile.mkdtemp(prefix='cw-')
         cwi18ndir = WebConfiguration.i18n_lib_dir()
-        print '-> extract messages:',
-        print 'schema',
+        print('-> extract messages:', end=' ')
+        print('schema', end=' ')
         schemapot = osp.join(tempdir, 'schema.pot')
         potfiles = [schemapot]
         potfiles.append(schemapot)
         # explicit close necessary else the file may not be yet flushed when
         # we'll using it below
-        schemapotstream = file(schemapot, 'w')
+        schemapotstream = open(schemapot, 'w')
         generate_schema_pot(schemapotstream.write, cubedir=None)
         schemapotstream.close()
-        print 'TAL',
+        print('TAL', end=' ')
         tali18nfile = osp.join(tempdir, 'tali18n.py')
         extract_from_tal(find(osp.join(BASEDIR, 'web'), ('.py', '.pt')),
                          tali18nfile)
-        print '-> generate .pot files.'
+        print('-> generate .pot files.')
         pyfiles = get_module_files(BASEDIR)
         pyfiles += globfind(osp.join(BASEDIR, 'misc', 'migration'), '*.py')
         schemafiles = globfind(osp.join(BASEDIR, 'schemas'), '*.py')
@@ -349,12 +350,12 @@
             if osp.exists(potfile):
                 potfiles.append(potfile)
             else:
-                print '-> WARNING: %s file was not generated' % potfile
-        print '-> merging %i .pot files' % len(potfiles)
+                print('-> WARNING: %s file was not generated' % potfile)
+        print('-> merging %i .pot files' % len(potfiles))
         cubicwebpot = osp.join(tempdir, 'cubicweb.pot')
         cmd = ['msgcat', '-o', cubicwebpot] + potfiles
         execute2(cmd)
-        print '-> merging main pot file with existing translations.'
+        print('-> merging main pot file with existing translations.')
         chdir(cwi18ndir)
         toedit = []
         for lang in CubicWebNoAppConfiguration.cw_languages():
@@ -368,10 +369,10 @@
         # cleanup
         rm(tempdir)
         # instructions pour la suite
-        print '-> regenerated CubicWeb\'s .po catalogs.'
-        print '\nYou can now edit the following files:'
-        print '* ' + '\n* '.join(toedit)
-        print 'when you are done, run "cubicweb-ctl i18ncube yourcube".'
+        print('-> regenerated CubicWeb\'s .po catalogs.')
+        print('\nYou can now edit the following files:')
+        print('* ' + '\n* '.join(toedit))
+        print('when you are done, run "cubicweb-ctl i18ncube yourcube".')
 
 
 class UpdateCubeCatalogCommand(Command):
@@ -398,25 +399,25 @@
     from subprocess import CalledProcessError
     for cubedir in cubes:
         if not osp.isdir(cubedir):
-            print '-> ignoring %s that is not a directory.' % cubedir
+            print('-> ignoring %s that is not a directory.' % cubedir)
             continue
         try:
             toedit = update_cube_catalogs(cubedir)
         except CalledProcessError as exc:
-            print '\n*** error while updating catalogs for cube', cubedir
-            print 'cmd:\n%s' % exc.cmd
-            print 'stdout:\n%s\nstderr:\n%s' % exc.data
+            print('\n*** error while updating catalogs for cube', cubedir)
+            print('cmd:\n%s' % exc.cmd)
+            print('stdout:\n%s\nstderr:\n%s' % exc.data)
         except Exception:
             import traceback
             traceback.print_exc()
-            print '*** error while updating catalogs for cube', cubedir
+            print('*** error while updating catalogs for cube', cubedir)
             return False
         else:
             # instructions pour la suite
             if toedit:
-                print '-> regenerated .po catalogs for cube %s.' % cubedir
-                print '\nYou can now edit the following files:'
-                print '* ' + '\n* '.join(toedit)
+                print('-> regenerated .po catalogs for cube %s.' % cubedir)
+                print('\nYou can now edit the following files:')
+                print('* ' + '\n* '.join(toedit))
                 print ('When you are done, run "cubicweb-ctl i18ninstance '
                        '<yourinstance>" to see changes in your instances.')
             return True
@@ -429,7 +430,7 @@
     from cubicweb.i18n import extract_from_tal, execute2
     cube = osp.basename(osp.normpath(cubedir))
     tempdir = tempfile.mkdtemp()
-    print underline_title('Updating i18n catalogs for cube %s' % cube)
+    print(underline_title('Updating i18n catalogs for cube %s' % cube))
     chdir(cubedir)
     if osp.exists(osp.join('i18n', 'entities.pot')):
         warn('entities.pot is deprecated, rename file to static-messages.pot (%s)'
@@ -439,20 +440,20 @@
         potfiles = [osp.join('i18n', 'static-messages.pot')]
     else:
         potfiles = []
-    print '-> extracting messages:',
-    print 'schema',
+    print('-> extracting messages:', end=' ')
+    print('schema', end=' ')
     schemapot = osp.join(tempdir, 'schema.pot')
     potfiles.append(schemapot)
     # explicit close necessary else the file may not be yet flushed when
     # we'll using it below
-    schemapotstream = file(schemapot, 'w')
+    schemapotstream = open(schemapot, 'w')
     generate_schema_pot(schemapotstream.write, cubedir)
     schemapotstream.close()
-    print 'TAL',
+    print('TAL', end=' ')
     tali18nfile = osp.join(tempdir, 'tali18n.py')
     ptfiles = find('.', ('.py', '.pt'), blacklist=STD_BLACKLIST+('test',))
     extract_from_tal(ptfiles, tali18nfile)
-    print 'Javascript'
+    print('Javascript')
     jsfiles =  [jsfile for jsfile in find('.', '.js')
                 if osp.basename(jsfile).startswith('cub')]
     if jsfiles:
@@ -463,7 +464,7 @@
         # no pot file created if there are no string to translate
         if osp.exists(tmppotfile):
             potfiles.append(tmppotfile)
-    print '-> creating cube-specific catalog'
+    print('-> creating cube-specific catalog')
     tmppotfile = osp.join(tempdir, 'generated.pot')
     cubefiles = find('.', '.py', blacklist=STD_BLACKLIST+('test',))
     cubefiles.append(tali18nfile)
@@ -473,20 +474,20 @@
     if osp.exists(tmppotfile): # doesn't exists of no translation string found
         potfiles.append(tmppotfile)
     potfile = osp.join(tempdir, 'cube.pot')
-    print '-> merging %i .pot files' % len(potfiles)
+    print('-> merging %i .pot files' % len(potfiles))
     cmd = ['msgcat', '-o', potfile]
     cmd.extend(potfiles)
     execute2(cmd)
     if not osp.exists(potfile):
-        print 'no message catalog for cube', cube, 'nothing to translate'
+        print('no message catalog for cube', cube, 'nothing to translate')
         # cleanup
         rm(tempdir)
         return ()
-    print '-> merging main pot file with existing translations:',
+    print('-> merging main pot file with existing translations:', end=' ')
     chdir('i18n')
     toedit = []
     for lang in CubicWebNoAppConfiguration.cw_languages():
-        print lang,
+        print(lang, end=' ')
         cubepo = '%s.po' % lang
         if not osp.exists(cubepo):
             shutil.copy(potfile, cubepo)
@@ -496,7 +497,7 @@
             ensure_fs_mode(cubepo)
             shutil.move('%snew' % cubepo, cubepo)
         toedit.append(osp.abspath(cubepo))
-    print
+    print()
     # cleanup
     rm(tempdir)
     return toedit
@@ -620,7 +621,7 @@
                     " Please specify it using the --directory option")
             cubesdir = cubespath[0]
         if not osp.isdir(cubesdir):
-            print "-> creating cubes directory", cubesdir
+            print("-> creating cubes directory", cubesdir)
             try:
                 mkdir(cubesdir)
             except OSError as err:
@@ -649,7 +650,8 @@
         if verbose:
             longdesc = raw_input(
                 'Enter a long description (leave empty to reuse the short one): ')
-        dependencies = {'cubicweb': '>= %s' % cubicwebversion}
+        dependencies = {'cubicweb': '>= %s' % cubicwebversion,
+                        'six': '>= 1.4.0',}
         if verbose:
             dependencies.update(self._ask_for_dependencies())
         context = {'cubename' : cubename,
@@ -710,7 +712,7 @@
         requests = {}
         for filepath in args:
             try:
-                stream = file(filepath)
+                stream = open(filepath)
             except OSError as ex:
                 raise BadCommandUsage("can't open rql log file %s: %s"
                                       % (filepath, ex))
@@ -731,17 +733,17 @@
                 except Exception as exc:
                     sys.stderr.write('Line %s: %s (%s)\n' % (lineno, exc, line))
         stat = []
-        for rql, times in requests.iteritems():
+        for rql, times in requests.items():
             stat.append( (sum(time[0] for time in times),
                           sum(time[1] for time in times),
                           len(times), rql) )
         stat.sort()
         stat.reverse()
         total_time = sum(clocktime for clocktime, cputime, occ, rql in stat) * 0.01
-        print 'Percentage;Cumulative Time (clock);Cumulative Time (CPU);Occurences;Query'
+        print('Percentage;Cumulative Time (clock);Cumulative Time (CPU);Occurences;Query')
         for clocktime, cputime, occ, rql in stat:
-            print '%.2f;%.2f;%.2f;%s;%s' % (clocktime/total_time, clocktime,
-                                            cputime, occ, rql)
+            print('%.2f;%.2f;%.2f;%s;%s' % (clocktime/total_time, clocktime,
+                                            cputime, occ, rql))
 
 
 class GenerateSchema(Command):
--- a/devtools/fake.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/devtools/fake.py	Thu Dec 10 12:34:15 2015 +0100
@@ -22,6 +22,8 @@
 
 from contextlib import contextmanager
 
+from six import string_types
+
 from logilab.database import get_db_helper
 
 from cubicweb.req import RequestSessionBase
@@ -91,7 +93,7 @@
 
     def set_request_header(self, header, value, raw=False):
         """set an incoming HTTP header (for test purpose only)"""
-        if isinstance(value, basestring):
+        if isinstance(value, string_types):
             value = [value]
         if raw:
             # adding encoded header is important, else page content
@@ -110,7 +112,7 @@
     def build_url_params(self, **kwargs):
         # overriden to get predictable resultts
         args = []
-        for param, values in sorted(kwargs.iteritems()):
+        for param, values in sorted(kwargs.items()):
             if not isinstance(values, (list, tuple)):
                 values = (values,)
             for value in values:
--- a/devtools/fill.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/devtools/fill.py	Thu Dec 10 12:34:15 2015 +0100
@@ -17,6 +17,7 @@
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """This modules defines func / methods for creating test repositories"""
+from __future__ import print_function
 
 __docformat__ = "restructuredtext en"
 
@@ -25,6 +26,10 @@
 from copy import deepcopy
 from datetime import datetime, date, time, timedelta
 from decimal import Decimal
+import inspect
+
+from six import text_type, add_metaclass
+from six.moves import range
 
 from logilab.common import attrdict
 from logilab.mtconverter import xml_escape
@@ -173,7 +178,7 @@
     generate_tztime = generate_time # XXX implementation should add a timezone
 
     def generate_bytes(self, entity, attrname, index, format=None):
-        fakefile = Binary("%s%s" % (attrname, index))
+        fakefile = Binary(("%s%s" % (attrname, index)).encode('ascii'))
         fakefile.filename = u"file_%s" % attrname
         return fakefile
 
@@ -224,7 +229,7 @@
         """
         for cst in self.eschema.rdef(attrname).constraints:
             if isinstance(cst, StaticVocabularyConstraint):
-                return unicode(choice(cst.vocabulary()))
+                return text_type(choice(cst.vocabulary()))
         return None
 
     # XXX nothing to do here
@@ -254,13 +259,15 @@
         for attrname, attrvalue in classdict.items():
             if callable(attrvalue):
                 if attrname.startswith('generate_') and \
-                       attrvalue.func_code.co_argcount < 2:
+                       len(inspect.getargspec(attrvalue).args) < 2:
                     raise TypeError('generate_xxx must accept at least 1 argument')
                 setattr(_ValueGenerator, attrname, attrvalue)
         return type.__new__(mcs, name, bases, classdict)
 
+
+@add_metaclass(autoextend)
 class ValueGenerator(_ValueGenerator):
-    __metaclass__ = autoextend
+    pass
 
 
 def _default_choice_func(etype, attrname):
@@ -286,7 +293,7 @@
                         returns acceptable values for this attribute
     """
     queries = []
-    for index in xrange(entity_num):
+    for index in range(entity_num):
         restrictions = []
         args = {}
         for attrname, value in make_entity(etype, schema, vreg, index, choice_func).items():
@@ -347,7 +354,7 @@
                 fmt = vreg.property_value('ui.float-format')
                 value = fmt % value
             else:
-                value = unicode(value)
+                value = text_type(value)
     return entity
 
 
@@ -363,7 +370,7 @@
             rql += ', %s is %s' % (selectvar, objtype)
         rset = cnx.execute(rql)
     except Exception:
-        print "could restrict eid_list with given constraints (%r)" % constraints
+        print("could restrict eid_list with given constraints (%r)" % constraints)
         return []
     return set(eid for eid, in rset.rows)
 
@@ -508,8 +515,8 @@
                     break
         else:
             # FIXME: 20 should be read from config
-            subjeidsiter = [choice(tuple(subjeids)) for i in xrange(min(len(subjeids), 20))]
-            objeidsiter = [choice(tuple(objeids)) for i in xrange(min(len(objeids), 20))]
+            subjeidsiter = [choice(tuple(subjeids)) for i in range(min(len(subjeids), 20))]
+            objeidsiter = [choice(tuple(objeids)) for i in range(min(len(objeids), 20))]
             for subjeid, objeid in zip(subjeidsiter, objeidsiter):
                 if subjeid != objeid and not (subjeid, objeid) in used:
                     used.add( (subjeid, objeid) )
--- a/devtools/htmlparser.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/devtools/htmlparser.py	Thu Dec 10 12:34:15 2015 +0100
@@ -20,7 +20,7 @@
 import re
 import sys
 from xml import sax
-from cStringIO import StringIO
+from io import BytesIO
 
 from lxml import etree
 
@@ -33,7 +33,7 @@
 
 ERR_COUNT = 0
 
-_REM_SCRIPT_RGX = re.compile(r"<script[^>]*>.*?</script>", re.U|re.M|re.I|re.S)
+_REM_SCRIPT_RGX = re.compile(br"<script[^>]*>.*?</script>", re.M|re.I|re.S)
 def _remove_script_tags(data):
     """Remove the script (usually javascript) tags to help the lxml
     XMLParser / HTMLParser do their job. Without that, they choke on
@@ -70,7 +70,7 @@
     #
     # using that, we'll miss most actual validation error we want to
     # catch. For now, use dumb regexp
-    return _REM_SCRIPT_RGX.sub('', data)
+    return _REM_SCRIPT_RGX.sub(b'', data)
 
 
 class Validator(object):
@@ -164,10 +164,10 @@
 
     def _parse(self, data):
         inpsrc = sax.InputSource()
-        inpsrc.setByteStream(StringIO(data))
+        inpsrc.setByteStream(BytesIO(data))
         try:
             self._parser.parse(inpsrc)
-        except sax.SAXParseException, exc:
+        except sax.SAXParseException as exc:
             new_exc = AssertionError(u'invalid document: %s' % exc)
             new_exc.position = (exc._linenum, exc._colnum)
             raise new_exc
@@ -209,7 +209,7 @@
     def matching_nodes(self, tag, **attrs):
         for elt in self.etree.iterfind(self._iterstr(tag)):
             eltattrs  = elt.attrib
-            for attr, value in attrs.iteritems():
+            for attr, value in attrs.items():
                 try:
                     if eltattrs[attr] != value:
                         break
--- a/devtools/httptest.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/devtools/httptest.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,17 +18,18 @@
 """this module contains base classes and utilities for integration with running
 http server
 """
+from __future__ import print_function
+
 __docformat__ = "restructuredtext en"
 
 import random
 import threading
 import socket
-import httplib
-from urlparse import urlparse
 
-from twisted.internet import reactor, error
+from six.moves import range, http_client
+from six.moves.urllib.parse import urlparse
 
-from cubicweb.etwist.server import run
+
 from cubicweb.devtools.testlib import CubicWebTC
 from cubicweb.devtools import ApptestConfiguration
 
@@ -89,6 +90,8 @@
     configcls = CubicWebServerConfig
 
     def start_server(self):
+        from twisted.internet import reactor
+        from cubicweb.etwist.server import run
         # use a semaphore to avoid starting test while the http server isn't
         # fully initilialized
         semaphore = threading.Semaphore(0)
@@ -110,12 +113,13 @@
         #pre init utils connection
         parseurl = urlparse(self.config['base-url'])
         assert parseurl.port == self.config['port'], (self.config['base-url'], self.config['port'])
-        self._web_test_cnx = httplib.HTTPConnection(parseurl.hostname,
-                                                    parseurl.port)
+        self._web_test_cnx = http_client.HTTPConnection(parseurl.hostname,
+                                                        parseurl.port)
         self._ident_cookie = None
 
     def stop_server(self, timeout=15):
         """Stop the webserver, waiting for the thread to return"""
+        from twisted.internet import reactor
         if self._web_test_cnx is None:
             self.web_logout()
             self._web_test_cnx.close()
@@ -139,7 +143,7 @@
             passwd = user
         response = self.web_get("login?__login=%s&__password=%s" %
                                 (user, passwd))
-        assert response.status == httplib.SEE_OTHER, response.status
+        assert response.status == http_client.SEE_OTHER, response.status
         self._ident_cookie = response.getheader('Set-Cookie')
         assert self._ident_cookie
         return True
@@ -151,7 +155,7 @@
         self._ident_cookie = None
 
     def web_request(self, path='', method='GET', body=None, headers=None):
-        """Return an httplib.HTTPResponse object for the specified path
+        """Return an http_client.HTTPResponse object for the specified path
 
         Use available credential if available.
         """
@@ -174,9 +178,10 @@
         self.start_server()
 
     def tearDown(self):
+        from twisted.internet import error
         try:
             self.stop_server()
         except error.ReactorNotRunning as err:
             # Server could be launched manually
-            print err
+            print(err)
         super(CubicWebServerTC, self).tearDown()
--- a/devtools/instrument.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/devtools/instrument.py	Thu Dec 10 12:34:15 2015 +0100
@@ -14,6 +14,7 @@
 # You should have received a copy of the GNU Lesser General Public License along
 # with this program. If not, see <http://www.gnu.org/licenses/>.
 """Instrumentation utilities"""
+from __future__ import print_function
 
 import os
 
@@ -45,10 +46,10 @@
         return _COLORS[key]
 
 def warn(msg, *args):
-    print 'WARNING: %s' % (msg % args)
+    print('WARNING: %s' % (msg % args))
 
 def info(msg):
-    print 'INFO: ' + msg
+    print('INFO: ' + msg)
 
 
 class PropagationAnalyzer(object):
@@ -185,7 +186,7 @@
 
     def add_colors_legend(self, graph):
         """Add a legend of used colors to the graph."""
-        for package, color in sorted(_COLORS.iteritems()):
+        for package, color in sorted(_COLORS.items()):
             graph.add_node(package, color=color, fontcolor=color, shape='record')
 
 
--- a/devtools/qunit.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/devtools/qunit.py	Thu Dec 10 12:34:15 2015 +0100
@@ -15,53 +15,28 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
+from __future__ import absolute_import
 
 import os, os.path as osp
-from tempfile import mkdtemp, NamedTemporaryFile, TemporaryFile
-import tempfile
-from Queue import Queue, Empty
-from subprocess import Popen, check_call, CalledProcessError
-from shutil import rmtree, copy as copyfile
-from uuid import uuid4
+import errno
+from tempfile import mkdtemp
+from subprocess import Popen, PIPE, STDOUT
+
+from six.moves.queue import Queue, Empty
 
 # imported by default to simplify further import statements
 from logilab.common.testlib import unittest_main, with_tempdir, InnerTest, Tags
-from logilab.common.shellutils import getlogin
+import webtest.http
 
 import cubicweb
 from cubicweb.view import View
 from cubicweb.web.controller import Controller
 from cubicweb.web.views.staticcontrollers import StaticFileController, STATIC_CONTROLLERS
-from cubicweb.devtools.httptest import CubicWebServerTC
-
-
-class VerboseCalledProcessError(CalledProcessError):
-
-    def __init__(self, returncode, command, stdout, stderr):
-        super(VerboseCalledProcessError, self).__init__(returncode, command)
-        self.stdout = stdout
-        self.stderr = stderr
-
-    def __str__(self):
-        str = [ super(VerboseCalledProcessError, self).__str__()]
-        if self.stdout.strip():
-            str.append('******************')
-            str.append('* process stdout *')
-            str.append('******************')
-            str.append(self.stdout)
-        if self.stderr.strip():
-            str.append('******************')
-            str.append('* process stderr *')
-            str.append('******************')
-            str.append(self.stderr)
-        return '\n'.join(str)
-
+from cubicweb.devtools import webtest as cwwebtest
 
 
 class FirefoxHelper(object):
 
-    profile_name_mask = 'PYTEST_PROFILE_%(uid)s'
-
     def __init__(self, url=None):
         self._process = None
         self._profile_dir = mkdtemp(prefix='cwtest-ffxprof-')
@@ -70,6 +45,17 @@
             self.firefox_cmd = [osp.join(osp.dirname(__file__), 'data', 'xvfb-run.sh'),
                                 '-a', '-s', '-noreset -screen 0 800x600x24'] + self.firefox_cmd
 
+    def test(self):
+        try:
+            proc = Popen(['firefox', '--help'], stdout=PIPE, stderr=STDOUT)
+            stdout, _ = proc.communicate()
+            return proc.returncode == 0, stdout
+        except OSError as exc:
+            if exc.errno == errno.ENOENT:
+                msg = '[%s] %s' % (errno.errorcode[exc.errno], exc.strerror)
+                return False, msg
+            raise
+
     def start(self, url):
         self.stop()
         cmd = self.firefox_cmd + ['-silent', '--profile', self._profile_dir,
@@ -88,60 +74,46 @@
         self.stop()
 
 
-class QUnitTestCase(CubicWebServerTC):
+class QUnitTestCase(cwwebtest.CubicWebTestTC):
 
-    tags = CubicWebServerTC.tags | Tags(('qunit',))
+    tags = cwwebtest.CubicWebTestTC.tags | Tags(('qunit',))
 
     # testfile, (dep_a, dep_b)
     all_js_tests = ()
 
     def setUp(self):
-        self.config.global_set_option('access-control-allow-origin', '*')
         super(QUnitTestCase, self).setUp()
         self.test_queue = Queue()
         class MyQUnitResultController(QUnitResultController):
             tc = self
             test_queue = self.test_queue
         self._qunit_controller = MyQUnitResultController
-        self.vreg.register(MyQUnitResultController)
-        self.vreg.register(QUnitView)
-        self.vreg.register(CWSoftwareRootStaticController)
+        self.webapp.app.appli.vreg.register(MyQUnitResultController)
+        self.webapp.app.appli.vreg.register(QUnitView)
+        self.webapp.app.appli.vreg.register(CWDevtoolsStaticController)
+        self.server = webtest.http.StopableWSGIServer.create(self.webapp.app)
+        self.config.global_set_option('base-url', self.server.application_url)
 
     def tearDown(self):
+        self.server.shutdown()
+        self.webapp.app.appli.vreg.unregister(self._qunit_controller)
+        self.webapp.app.appli.vreg.unregister(QUnitView)
+        self.webapp.app.appli.vreg.unregister(CWDevtoolsStaticController)
         super(QUnitTestCase, self).tearDown()
-        self.vreg.unregister(self._qunit_controller)
-        self.vreg.unregister(QUnitView)
-        self.vreg.unregister(CWSoftwareRootStaticController)
-
-    def abspath(self, path):
-        """use self.__module__ to build absolute path if necessary"""
-        if not osp.isabs(path):
-           dirname = osp.dirname(__import__(self.__module__).__file__)
-           return osp.abspath(osp.join(dirname,path))
-        return path
 
     def test_javascripts(self):
         for args in self.all_js_tests:
-            test_file = self.abspath(args[0])
+            self.assertIn(len(args), (1, 2))
+            test_file = args[0]
             if len(args) > 1:
-                depends   = [self.abspath(dep) for dep in args[1]]
+                depends = args[1]
             else:
                 depends = ()
-            if len(args) > 2:
-                data   = [self.abspath(data) for data in args[2]]
-            else:
-                data = ()
-            for js_test in self._test_qunit(test_file, depends, data):
+            for js_test in self._test_qunit(test_file, depends):
                 yield js_test
 
     @with_tempdir
-    def _test_qunit(self, test_file, depends=(), data_files=(), timeout=10):
-        assert osp.exists(test_file), test_file
-        for dep in depends:
-            assert osp.exists(dep), dep
-        for data in data_files:
-            assert osp.exists(data), data
-
+    def _test_qunit(self, test_file, depends=(), timeout=10):
         QUnitView.test_file = test_file
         QUnitView.depends = depends
 
@@ -149,6 +121,9 @@
             self.test_queue.get(False)
 
         browser = FirefoxHelper()
+        isavailable, reason = browser.test()
+        if not isavailable:
+            self.fail('firefox not available or not working properly (%s)' % reason)
         browser.start(self.config['base-url'] + "?vid=qunit")
         test_count = 0
         error = False
@@ -188,6 +163,7 @@
     def publish(self, rset=None):
         event = self._cw.form['event']
         getattr(self, 'handle_%s' % event)()
+        return b''
 
     def handle_module_start(self):
         self.__class__._current_module_name = self._cw.form.get('name', '')
@@ -234,20 +210,15 @@
     def call(self, **kwargs):
         w = self.w
         req = self._cw
-        data = {
-            'jquery': req.data_url('jquery.js'),
-            'web_test': req.build_url('cwsoftwareroot/devtools/data'),
-        }
         w(u'''<!DOCTYPE html>
         <html>
         <head>
         <meta http-equiv="content-type" content="application/html; charset=UTF-8"/>
         <!-- JS lib used as testing framework -->
-        <link rel="stylesheet" type="text/css" media="all" href="%(web_test)s/qunit.css" />
-        <script src="%(jquery)s" type="text/javascript"></script>
-        <script src="%(web_test)s/cwmock.js" type="text/javascript"></script>
-        <script src="%(web_test)s/qunit.js" type="text/javascript"></script>'''
-        % data)
+        <link rel="stylesheet" type="text/css" media="all" href="/devtools/qunit.css" />
+        <script src="/data/jquery.js" type="text/javascript"></script>
+        <script src="/devtools/cwmock.js" type="text/javascript"></script>
+        <script src="/devtools/qunit.js" type="text/javascript"></script>''')
         w(u'<!-- result report tools -->')
         w(u'<script type="text/javascript">')
         w(u"var BASE_URL = '%s';" % req.base_url())
@@ -293,14 +264,11 @@
         w(u'</script>')
         w(u'<!-- Test script dependencies (tested code for example) -->')
 
-        prefix = len(cubicweb.CW_SOFTWARE_ROOT) + 1
         for dep in self.depends:
-            dep = req.build_url('cwsoftwareroot/') + dep[prefix:]
-            w(u'    <script src="%s" type="text/javascript"></script>' % dep)
+            w(u'    <script src="%s" type="text/javascript"></script>\n' % dep)
 
         w(u'    <!-- Test script itself -->')
-        test_url = req.build_url('cwsoftwareroot/') + self.test_file[prefix:]
-        w(u'    <script src="%s" type="text/javascript"></script>' % test_url)
+        w(u'    <script src="%s" type="text/javascript"></script>' % self.test_file)
         w(u'''  </head>
         <body>
         <div id="qunit-fixture"></div>
@@ -309,16 +277,16 @@
         </html>''')
 
 
-class CWSoftwareRootStaticController(StaticFileController):
-    __regid__ = 'cwsoftwareroot'
+class CWDevtoolsStaticController(StaticFileController):
+    __regid__ = 'devtools'
 
     def publish(self, rset=None):
-        staticdir = cubicweb.CW_SOFTWARE_ROOT
+        staticdir = osp.join(osp.dirname(__file__), 'data')
         relpath = self.relpath[len(self.__regid__) + 1:]
         return self.static_file(osp.join(staticdir, relpath))
 
 
-STATIC_CONTROLLERS.append(CWSoftwareRootStaticController)
+STATIC_CONTROLLERS.append(CWDevtoolsStaticController)
 
 
 if __name__ == '__main__':
--- a/devtools/repotest.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/devtools/repotest.py	Thu Dec 10 12:34:15 2015 +0100
@@ -19,6 +19,7 @@
 
 This module contains functions to initialize a new repository.
 """
+from __future__ import print_function
 
 __docformat__ = "restructuredtext en"
 
@@ -29,10 +30,9 @@
 def tuplify(mylist):
     return [tuple(item) for item in mylist]
 
-def snippet_cmp(a, b):
-    a = (a[0], [e.expression for e in a[1]])
-    b = (b[0], [e.expression for e in b[1]])
-    return cmp(a, b)
+def snippet_key(a):
+    # a[0] may be a dict or a key/value tuple
+    return (sorted(dict(a[0]).items()), [e.expression for e in a[1]])
 
 def test_plan(self, rql, expected, kwargs=None):
     with self.session.new_cnx() as cnx:
@@ -57,7 +57,7 @@
                               'expected %s queries, got %s' % (len(equeries), len(queries)))
             for i, (rql, sol) in enumerate(queries):
                 self.assertEqual(rql, equeries[i][0])
-                self.assertEqual(sorted(sol), sorted(equeries[i][1]))
+                self.assertEqual(sorted(sorted(x.items()) for x in sol), sorted(sorted(x.items()) for x in equeries[i][1]))
             idx = 2
         else:
             idx = 1
@@ -66,7 +66,7 @@
         self.assertEqual(len(step[-1]), len(expected[-1]),
                           'got %s child steps, expected %s' % (len(step[-1]), len(expected[-1])))
     except AssertionError:
-        print 'error on step ',
+        print('error on step ', end=' ')
         pprint(step[:-1])
         raise
     children = step[-1]
@@ -115,7 +115,7 @@
         schema_eids[x] = x.eid
     for x in schema.relations():
         schema_eids[x] = x.eid
-        for rdef in x.rdefs.itervalues():
+        for rdef in x.rdefs.values():
             schema_eids[(rdef.subject, rdef.rtype, rdef.object)] = rdef.eid
     return schema_eids
 
@@ -127,7 +127,7 @@
     for x in schema.relations():
         x.eid = schema_eids[x]
         schema._eid_index[x.eid] = x
-        for rdef in x.rdefs.itervalues():
+        for rdef in x.rdefs.values():
             rdef.eid = schema_eids[(rdef.subject, rdef.rtype, rdef.object)]
             schema._eid_index[rdef.eid] = rdef
 
@@ -187,7 +187,7 @@
         plan = self.qhelper.plan_factory(union, {}, FakeSession(self.repo))
         plan.preprocess(union)
         for select in union.children:
-            select.solutions.sort()
+            select.solutions.sort(key=lambda x: list(x.items()))
         #print '********* ppsolutions', solutions
         return union
 
@@ -197,7 +197,7 @@
 
     def setUp(self):
         self.o = self.repo.querier
-        self.session = self.repo._sessions.values()[0]
+        self.session = next(iter(self.repo._sessions.values()))
         self.ueid = self.session.user.eid
         assert self.ueid != -1
         self.repo._type_source_cache = {} # clear cache
@@ -238,7 +238,7 @@
         if simplify:
             rqlhelper.simplify(rqlst)
         for select in rqlst.children:
-            select.solutions.sort()
+            select.solutions.sort(key=lambda x: list(x.items()))
         return self.o.plan_factory(rqlst, kwargs, cnx)
 
     def _prepare(self, cnx, rql, kwargs=None):
@@ -286,13 +286,13 @@
         if rqlst.TYPE == 'select':
             self.repo.vreg.rqlhelper.annotate(rqlst)
             for select in rqlst.children:
-                select.solutions.sort()
+                select.solutions.sort(key=lambda x: list(x.items()))
         else:
-            rqlst.solutions.sort()
+            rqlst.solutions.sort(key=lambda x: list(x.items()))
         return self.o.plan_factory(rqlst, kwargs, cnx)
 
 
-# monkey patch some methods to get predicatable results #######################
+# monkey patch some methods to get predictable results #######################
 
 from cubicweb import rqlrewrite
 _orig_iter_relations = rqlrewrite.iter_relations
@@ -300,16 +300,15 @@
 _orig_build_variantes = rqlrewrite.RQLRewriter.build_variantes
 
 def _insert_snippets(self, snippets, varexistsmap=None):
-    _orig_insert_snippets(self, sorted(snippets, snippet_cmp), varexistsmap)
+    _orig_insert_snippets(self, sorted(snippets, key=snippet_key), varexistsmap)
 
 def _build_variantes(self, newsolutions):
     variantes = _orig_build_variantes(self, newsolutions)
     sortedvariantes = []
     for variante in variantes:
-        orderedkeys = sorted((k[1], k[2], v) for k, v in variante.iteritems())
-        variante = DumbOrderedDict(sorted(variante.iteritems(),
-                                          lambda a, b: cmp((a[0][1],a[0][2],a[1]),
-                                                           (b[0][1],b[0][2],b[1]))))
+        orderedkeys = sorted((k[1], k[2], v) for k, v in variante.items())
+        variante = DumbOrderedDict(sorted(variante.items(),
+                                          key=lambda a: (a[0][1], a[0][2], a[1])))
         sortedvariantes.append( (orderedkeys, variante) )
     return [v for ok, v in sorted(sortedvariantes)]
 
@@ -318,7 +317,7 @@
 
 def _check_permissions(*args, **kwargs):
     res, restricted = _orig_check_permissions(*args, **kwargs)
-    res = DumbOrderedDict(sorted(res.iteritems(), lambda a, b: cmp(a[1], b[1])))
+    res = DumbOrderedDict(sorted(res.items(), key=lambda x: [y.items() for y in x[1]]))
     return res, restricted
 
 def _dummy_check_permissions(self, rqlst):
--- a/devtools/stresstester.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/devtools/stresstester.py	Thu Dec 10 12:34:15 2015 +0100
@@ -41,6 +41,7 @@
 Copyright (c) 2003-2011 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
 http://www.logilab.fr/ -- mailto:contact@logilab.fr
 """
+from __future__ import print_function
 
 import os
 import sys
@@ -84,7 +85,7 @@
 
 def usage(status=0):
     """print usage string and exit"""
-    print __doc__ % basename(sys.argv[0])
+    print(__doc__ % basename(sys.argv[0]))
     sys.exit(status)
 
 
@@ -133,7 +134,7 @@
                                                            'nb-times=', 'nb-threads=',
                                                            'profile', 'report-output=',])
     except Exception as ex:
-        print ex
+        print(ex)
         usage(1)
     repeat = 100
     threads = 1
@@ -155,7 +156,7 @@
         elif opt in ('-P', '--profile'):
             prof_file = val
         elif opt in ('-o', '--report-output'):
-            report_output = file(val, 'w')
+            report_output = open(val, 'w')
     if len(args) != 2:
         usage(1)
     queries =  [query for query in lines(args[1]) if not query.startswith('#')]
@@ -166,7 +167,7 @@
     from cubicweb.cwconfig import instance_configuration
     config = instance_configuration(args[0])
     # get local access to the repository
-    print "Creating repo", prof_file
+    print("Creating repo", prof_file)
     repo = Repository(config, prof_file)
     cnxid = repo.connect(user, password=password)
     # connection to the CubicWeb repository
--- a/devtools/test/data/js_examples/dep_1.js	Wed Dec 09 18:42:13 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-a = 4;
--- a/devtools/test/data/js_examples/deps_2.js	Wed Dec 09 18:42:13 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-b = a +2;
--- a/devtools/test/data/js_examples/test_simple_failure.js	Wed Dec 09 18:42:13 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-$(document).ready(function() {
-
-  QUnit.module("air");
-
-  QUnit.test("test 1", function (assert) {
-      assert.equal(2, 4);
-  });
-
-  QUnit.test("test 2", function (assert) {
-      assert.equal('', '45');
-      assert.equal('1024', '32');
-  });
-
-  QUnit.module("able");
-  QUnit.test("test 3", function (assert) {
-      assert.deepEqual(1, 1);
-  });
-});
--- a/devtools/test/data/js_examples/test_simple_success.js	Wed Dec 09 18:42:13 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-$(document).ready(function() {
-
-  QUnit.module("air");
-
-  QUnit.test("test 1", function (assert) {
-      assert.equal(2, 2);
-  });
-
-  QUnit.test("test 2", function (assert) {
-      assert.equal('45', '45');
-  });
-
-  QUnit.module("able");
-  QUnit.test("test 3", function (assert) {
-      assert.deepEqual(1, 1);
-  });
-});
--- a/devtools/test/data/js_examples/test_with_dep.js	Wed Dec 09 18:42:13 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-$(document).ready(function() {
-
-  QUnit.module("air");
-
-  QUnit.test("test 1", function (assert) {
-      assert.equal(a, 4);
-  });
-
-});
--- a/devtools/test/data/js_examples/test_with_ordered_deps.js	Wed Dec 09 18:42:13 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-$(document).ready(function() {
-
-  QUnit.module("air");
-
-  QUnit.test("test 1", function (assert) {
-      assert.equal(b, 6);
-  });
-
-});
--- a/devtools/test/data/js_examples/utils.js	Wed Dec 09 18:42:13 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-function datetuple(d) {
-    return [d.getFullYear(), d.getMonth()+1, d.getDate(), 
-	    d.getHours(), d.getMinutes()];
-}
-    
-function pprint(obj) {
-    print('{');
-    for(k in obj) {
-	print('  ' + k + ' = ' + obj[k]);
-    }
-    print('}');
-}
-
-function arrayrepr(array) {
-    return '[' + array.join(', ') + ']';
-}
-    
-function assertArrayEquals(array1, array2) {
-    if (array1.length != array2.length) {
-	throw new crosscheck.AssertionFailure(array1.join(', ') + ' != ' + array2.join(', '));
-    }
-    for (var i=0; i<array1.length; i++) {
-	if (array1[i] != array2[i]) {
-	    
-	    throw new crosscheck.AssertionFailure(arrayrepr(array1) + ' and ' + arrayrepr(array2)
-						 + ' differs at index ' + i);
-	}
-    }
-}
--- a/devtools/test/data/schema.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/devtools/test/data/schema.py	Thu Dec 10 12:34:15 2015 +0100
@@ -30,4 +30,3 @@
     cost = Int()
     description	= String(maxsize=4096, fulltextindexed=True)
     identical_to = SubjectRelation('Bug', symmetric=True)
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devtools/test/data/static/js_examples/dep_1.js	Thu Dec 10 12:34:15 2015 +0100
@@ -0,0 +1,1 @@
+a = 4;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devtools/test/data/static/js_examples/deps_2.js	Thu Dec 10 12:34:15 2015 +0100
@@ -0,0 +1,1 @@
+b = a +2;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devtools/test/data/static/js_examples/test_simple_failure.js	Thu Dec 10 12:34:15 2015 +0100
@@ -0,0 +1,18 @@
+$(document).ready(function() {
+
+  QUnit.module("air");
+
+  QUnit.test("test 1", function (assert) {
+      assert.equal(2, 4);
+  });
+
+  QUnit.test("test 2", function (assert) {
+      assert.equal('', '45');
+      assert.equal('1024', '32');
+  });
+
+  QUnit.module("able");
+  QUnit.test("test 3", function (assert) {
+      assert.deepEqual(1, 1);
+  });
+});
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devtools/test/data/static/js_examples/test_simple_success.js	Thu Dec 10 12:34:15 2015 +0100
@@ -0,0 +1,17 @@
+$(document).ready(function() {
+
+  QUnit.module("air");
+
+  QUnit.test("test 1", function (assert) {
+      assert.equal(2, 2);
+  });
+
+  QUnit.test("test 2", function (assert) {
+      assert.equal('45', '45');
+  });
+
+  QUnit.module("able");
+  QUnit.test("test 3", function (assert) {
+      assert.deepEqual(1, 1);
+  });
+});
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devtools/test/data/static/js_examples/test_with_dep.js	Thu Dec 10 12:34:15 2015 +0100
@@ -0,0 +1,9 @@
+$(document).ready(function() {
+
+  QUnit.module("air");
+
+  QUnit.test("test 1", function (assert) {
+      assert.equal(a, 4);
+  });
+
+});
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devtools/test/data/static/js_examples/test_with_ordered_deps.js	Thu Dec 10 12:34:15 2015 +0100
@@ -0,0 +1,9 @@
+$(document).ready(function() {
+
+  QUnit.module("air");
+
+  QUnit.test("test 1", function (assert) {
+      assert.equal(b, 6);
+  });
+
+});
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devtools/test/data/static/js_examples/utils.js	Thu Dec 10 12:34:15 2015 +0100
@@ -0,0 +1,29 @@
+function datetuple(d) {
+    return [d.getFullYear(), d.getMonth()+1, d.getDate(), 
+	    d.getHours(), d.getMinutes()];
+}
+    
+function pprint(obj) {
+    print('{');
+    for(k in obj) {
+	print('  ' + k + ' = ' + obj[k]);
+    }
+    print('}');
+}
+
+function arrayrepr(array) {
+    return '[' + array.join(', ') + ']';
+}
+    
+function assertArrayEquals(array1, array2) {
+    if (array1.length != array2.length) {
+	throw new crosscheck.AssertionFailure(array1.join(', ') + ' != ' + array2.join(', '));
+    }
+    for (var i=0; i<array1.length; i++) {
+	if (array1[i] != array2[i]) {
+	    
+	    throw new crosscheck.AssertionFailure(arrayrepr(array1) + ' and ' + arrayrepr(array2)
+						 + ' differs at index ' + i);
+	}
+    }
+}
--- a/devtools/test/unittest_dbfill.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/devtools/test/unittest_dbfill.py	Thu Dec 10 12:34:15 2015 +0100
@@ -21,6 +21,9 @@
 import os.path as osp
 import re
 import datetime
+import io
+
+from six.moves import range
 
 from logilab.common.testlib import TestCase, unittest_main
 
@@ -50,7 +53,7 @@
             return None
 
     def _available_Person_firstname(self, etype, attrname):
-        return [f.strip() for f in file(osp.join(DATADIR, 'firstnames.txt'))]
+        return [f.strip() for f in io.open(osp.join(DATADIR, 'firstnames.txt'), encoding='latin1')]
 
     def setUp(self):
         config = ApptestConfiguration('data', apphome=DATADIR)
@@ -86,7 +89,7 @@
         # Test for random index
         for index in range(5):
             cost_value = self.bug_valgen.generate_attribute_value({}, 'cost', index)
-            self.assertIn(cost_value, range(index+1))
+            self.assertIn(cost_value, list(range(index+1)))
 
     def test_date(self):
         """test date generation"""
--- a/devtools/test/unittest_httptest.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/devtools/test/unittest_httptest.py	Thu Dec 10 12:34:15 2015 +0100
@@ -17,7 +17,7 @@
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """unittest for cubicweb.devtools.httptest module"""
 
-import httplib
+from six.moves import http_client
 
 from logilab.common.testlib import Tags
 from cubicweb.devtools.httptest import CubicWebServerTC
@@ -28,12 +28,12 @@
     def test_response(self):
         try:
             response = self.web_get()
-        except httplib.NotConnected as ex:
+        except http_client.NotConnected as ex:
             self.fail("Can't connection to test server: %s" % ex)
 
     def test_response_anon(self):
         response = self.web_get()
-        self.assertEqual(response.status, httplib.OK)
+        self.assertEqual(response.status, http_client.OK)
 
     def test_base_url(self):
         if self.config['base-url'] not in self.web_get().read():
@@ -47,20 +47,20 @@
 
     def test_response_denied(self):
         response = self.web_get()
-        self.assertEqual(response.status, httplib.FORBIDDEN)
+        self.assertEqual(response.status, http_client.FORBIDDEN)
 
     def test_login(self):
         response = self.web_get()
-        if response.status != httplib.FORBIDDEN:
+        if response.status != http_client.FORBIDDEN:
             self.skipTest('Already authenticated, "test_response_denied" must have failed')
         # login
         self.web_login(self.admlogin, self.admpassword)
         response = self.web_get()
-        self.assertEqual(response.status, httplib.OK, response.body)
+        self.assertEqual(response.status, http_client.OK, response.body)
         # logout
         self.web_logout()
         response = self.web_get()
-        self.assertEqual(response.status, httplib.FORBIDDEN, response.body)
+        self.assertEqual(response.status, http_client.FORBIDDEN, response.body)
 
 
 
--- a/devtools/test/unittest_qunit.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/devtools/test/unittest_qunit.py	Thu Dec 10 12:34:15 2015 +0100
@@ -1,15 +1,10 @@
-from logilab.common.testlib import unittest_main
-from cubicweb.devtools.qunit import QUnitTestCase
-
-from os import path as osp
-
-JSTESTDIR = osp.abspath(osp.join(osp.dirname(__file__), 'data', 'js_examples'))
+from cubicweb.devtools import qunit
 
 
 def js(name):
-    return osp.join(JSTESTDIR, name)
+    return '/static/js_examples/' + name
 
-class QUnitTestCaseTC(QUnitTestCase):
+class QUnitTestCaseTC(qunit.QUnitTestCase):
 
     all_js_tests = (
                     (js('test_simple_success.js'),),
@@ -28,4 +23,5 @@
 
 
 if __name__ == '__main__':
-    unittest_main()
+    from unittest import main
+    main()
--- a/devtools/test/unittest_testlib.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/devtools/test/unittest_testlib.py	Thu Dec 10 12:34:15 2015 +0100
@@ -17,9 +17,10 @@
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """unittests for cw.devtools.testlib module"""
 
-from cStringIO import StringIO
+from io import BytesIO, StringIO
+from unittest import TextTestRunner
 
-from unittest import TextTestRunner
+from six import PY2
 
 from logilab.common.testlib import TestSuite, TestCase, unittest_main
 from logilab.common.registry import yes
@@ -33,7 +34,7 @@
         class entity:
             cw_etype = 'Entity'
             eid = 0
-        sio = StringIO('hop\n')
+        sio = BytesIO(b'hop\n')
         form = CubicWebTC.fake_form('import',
                                     {'file': ('filename.txt', sio),
                                      'encoding': u'utf-8',
@@ -51,7 +52,7 @@
 class WebTestTC(TestCase):
 
     def setUp(self):
-        output = StringIO()
+        output = BytesIO() if PY2 else StringIO()
         self.runner = TextTestRunner(stream=output)
 
     def test_error_raised(self):
--- a/devtools/test/unittest_webtest.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/devtools/test/unittest_webtest.py	Thu Dec 10 12:34:15 2015 +0100
@@ -1,4 +1,4 @@
-import httplib
+from six.moves import http_client
 
 from logilab.common.testlib import Tags
 from cubicweb.devtools.webtest import CubicWebTestTC
@@ -21,19 +21,19 @@
 
     def test_reponse_denied(self):
         res = self.webapp.get('/', expect_errors=True)
-        self.assertEqual(httplib.FORBIDDEN, res.status_int)
+        self.assertEqual(http_client.FORBIDDEN, res.status_int)
 
     def test_login(self):
         res = self.webapp.get('/', expect_errors=True)
-        self.assertEqual(httplib.FORBIDDEN, res.status_int)
+        self.assertEqual(http_client.FORBIDDEN, res.status_int)
 
         self.login(self.admlogin, self.admpassword)
         res = self.webapp.get('/')
-        self.assertEqual(httplib.OK, res.status_int)
+        self.assertEqual(http_client.OK, res.status_int)
 
         self.logout()
         res = self.webapp.get('/', expect_errors=True)
-        self.assertEqual(httplib.FORBIDDEN, res.status_int)
+        self.assertEqual(http_client.FORBIDDEN, res.status_int)
 
 
 if __name__ == '__main__':
--- a/devtools/testlib.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/devtools/testlib.py	Thu Dec 10 12:34:15 2015 +0100
@@ -16,19 +16,22 @@
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """this module contains base classes and utilities for cubicweb tests"""
+from __future__ import print_function
+
 __docformat__ = "restructuredtext en"
 
 import sys
 import re
-import urlparse
 from os.path import dirname, join, abspath
-from urllib import unquote
 from math import log
 from contextlib import contextmanager
 from warnings import warn
-from types import NoneType
 from itertools import chain
 
+from six import text_type, string_types
+from six.moves import range
+from six.moves.urllib.parse import urlparse, parse_qs, unquote as urlunquote
+
 import yams.schema
 
 from logilab.common.testlib import TestCase, InnerTest, Tags
@@ -60,7 +63,7 @@
     def do_view(self, arg):
         import webbrowser
         data = self._getval(arg)
-        with file('/tmp/toto.html', 'w') as toto:
+        with open('/tmp/toto.html', 'w') as toto:
             toto.write(data)
         webbrowser.open('file:///tmp/toto.html')
 
@@ -85,7 +88,7 @@
 
 class JsonValidator(object):
     def parse_string(self, data):
-        return json.loads(data)
+        return json.loads(data.decode('ascii'))
 
 @contextmanager
 def real_error_handling(app):
@@ -283,7 +286,7 @@
         """provide a new RepoAccess object for a given user
 
         The access is automatically closed at the end of the test."""
-        login = unicode(login)
+        login = text_type(login)
         access = RepoAccess(self.repo, login, self.requestcls)
         self._open_access.add(access)
         return access
@@ -310,7 +313,7 @@
         db_handler.restore_database(self.test_db_id)
         self.repo = db_handler.get_repo(startup=True)
         # get an admin session (without actual login)
-        login = unicode(db_handler.config.default_admin_config['login'])
+        login = text_type(db_handler.config.default_admin_config['login'])
         self.admin_access = self.new_access(login)
         self._admin_session = self.admin_access._session
 
@@ -323,8 +326,11 @@
 
         Configuration is cached on the test class.
         """
+        if cls is CubicWebTC:
+            # Prevent direct use of CubicWebTC directly to avoid database
+            # caching issues
+            return None
         try:
-            assert not cls is CubicWebTC, "Don't use CubicWebTC directly to prevent database caching issue"
             return cls.__dict__['_config']
         except KeyError:
             home = abspath(join(dirname(sys.modules[cls.__module__].__file__), cls.appid))
@@ -345,7 +351,7 @@
         been properly bootstrapped.
         """
         admincfg = config.default_admin_config
-        cls.admlogin = unicode(admincfg['login'])
+        cls.admlogin = text_type(admincfg['login'])
         cls.admpassword = admincfg['password']
         # uncomment the line below if you want rql queries to be logged
         #config.global_set_option('query-log-file',
@@ -366,7 +372,6 @@
             config.global_set_option('embed-allowed', re.compile('.*'))
         except Exception: # not in server only configuration
             pass
-        config.set_anonymous_allowed(cls.anonymous_allowed)
 
     @property
     def vreg(self):
@@ -404,6 +409,7 @@
                 self.__class__._repo_init_failed = ex
                 raise
             self.addCleanup(self._close_access)
+        self.config.set_anonymous_allowed(self.anonymous_allowed)
         self.setup_database()
         MAILBOX[:] = [] # reset mailbox
 
@@ -453,14 +459,14 @@
         if password is None:
             password = login
         if login is not None:
-            login = unicode(login)
+            login = text_type(login)
         user = req.create_entity('CWUser', login=login,
                                  upassword=password, **kwargs)
         req.execute('SET X in_group G WHERE X eid %%(x)s, G name IN(%s)'
                     % ','.join(repr(str(g)) for g in groups),
                     {'x': user.eid})
         if email is not None:
-            req.create_entity('EmailAddress', address=unicode(email),
+            req.create_entity('EmailAddress', address=text_type(email),
                               reverse_primary_email=user)
         user.cw_clear_relation_cache('in_group', 'subject')
         if commit:
@@ -518,10 +524,10 @@
         similar to `orig_permissions.update(partial_perms)`.
         """
         torestore = []
-        for erschema, etypeperms in chain(perm_overrides, perm_kwoverrides.iteritems()):
-            if isinstance(erschema, basestring):
+        for erschema, etypeperms in chain(perm_overrides, perm_kwoverrides.items()):
+            if isinstance(erschema, string_types):
                 erschema = self.schema[erschema]
-            for action, actionperms in etypeperms.iteritems():
+            for action, actionperms in etypeperms.items():
                 origperms = erschema.permissions[action]
                 erschema.set_action_permissions(action, actionperms)
                 torestore.append([erschema, action, origperms])
@@ -737,8 +743,8 @@
         req = self.request(url=url)
         if isinstance(url, unicode):
             url = url.encode(req.encoding) # req.setup_params() expects encoded strings
-        querystring = urlparse.urlparse(url)[-2]
-        params = urlparse.parse_qs(querystring)
+        querystring = urlparse(url)[-2]
+        params = parse_qs(querystring)
         req.setup_params(params)
         return req
 
@@ -751,8 +757,8 @@
         with self.admin_access.web_request(url=url) as req:
             if isinstance(url, unicode):
                 url = url.encode(req.encoding) # req.setup_params() expects encoded strings
-            querystring = urlparse.urlparse(url)[-2]
-            params = urlparse.parse_qs(querystring)
+            querystring = urlparse(url)[-2]
+            params = parse_qs(querystring)
             req.setup_params(params)
             yield req
 
@@ -791,7 +797,7 @@
             path = location
             params = {}
         else:
-            cleanup = lambda p: (p[0], unquote(p[1]))
+            cleanup = lambda p: (p[0], urlunquote(p[1]))
             params = dict(cleanup(p.split('=', 1)) for p in params.split('&') if p)
         if path.startswith(req.base_url()): # may be relative
             path = path[len(req.base_url()):]
@@ -884,7 +890,7 @@
         }
     # maps vid : validator name (override content_type_validators)
     vid_validators = dict((vid, htmlparser.VALMAP[valkey])
-                          for vid, valkey in VIEW_VALIDATORS.iteritems())
+                          for vid, valkey in VIEW_VALIDATORS.items())
 
 
     def view(self, vid, rset=None, req=None, template='main-template',
@@ -907,8 +913,11 @@
         view = viewsreg.select(vid, req, rset=rset, **kwargs)
         # set explicit test description
         if rset is not None:
+            # coerce to "bytes" on py2 because the description will be sent to
+            # sys.stdout/stderr which takes "bytes" on py2 and "unicode" on py3
+            rql = str(rset.printable_rql())
             self.set_description("testing vid=%s defined in %s with (%s)" % (
-                vid, view.__module__, rset.printable_rql()))
+                vid, view.__module__, rql))
         else:
             self.set_description("testing vid=%s defined in %s without rset" % (
                 vid, view.__module__))
@@ -940,7 +949,9 @@
                 msg = '[%s in %s] %s' % (klass, view.__regid__, exc)
             except Exception:
                 msg = '[%s in %s] undisplayable exception' % (klass, view.__regid__)
-            raise AssertionError, msg, tcbk
+            exc = AssertionError(msg)
+            exc.__traceback__ = tcbk
+            raise exc
         return self._check_html(output, view, template)
 
     def get_validator(self, view=None, content_type=None, output=None):
@@ -953,11 +964,11 @@
         if content_type is None:
             content_type = 'text/html'
         if content_type in ('text/html', 'application/xhtml+xml') and output:
-            if output.startswith('<!DOCTYPE html>'):
+            if output.startswith(b'<!DOCTYPE html>'):
                 # only check XML well-formness since HTMLValidator isn't html5
                 # compatible and won't like various other extensions
                 default_validator = htmlparser.XMLSyntaxValidator
-            elif output.startswith('<?xml'):
+            elif output.startswith(b'<?xml'):
                 default_validator = htmlparser.DTDValidator
             else:
                 default_validator = htmlparser.HTMLValidator
@@ -973,6 +984,9 @@
     def _check_html(self, output, view, template='main-template'):
         """raises an exception if the HTML is invalid"""
         output = output.strip()
+        if isinstance(output, text_type):
+            # XXX
+            output = output.encode('utf-8')
         validator = self.get_validator(view, output=output)
         if validator is None:
             return output # return raw output if no validator is defined
@@ -998,7 +1012,7 @@
                 str_exc = str(exc)
             except Exception:
                 str_exc = 'undisplayable exception'
-            msg += str_exc
+            msg += str_exc.encode(sys.getdefaultencoding(), 'replace')
             if content is not None:
                 position = getattr(exc, "position", (0,))[0]
                 if position:
@@ -1015,7 +1029,9 @@
                                          for idx, line in enumerate(content)
                                          if line_context_filter(idx+1, position))
                     msg += u'\nfor content:\n%s' % content
-            raise AssertionError, msg, tcbk
+            exc = AssertionError(msg)
+            exc.__traceback__ = tcbk
+            raise exc
 
     def assertDocTestFile(self, testfile):
         # doctest returns tuple (failure_count, test_count)
@@ -1096,7 +1112,7 @@
     # new num for etype = max(current num, sum(num for possible target etypes))
     #
     # XXX we should first check there is no cycle then propagate changes
-    for (rschema, etype), targets in relmap.iteritems():
+    for (rschema, etype), targets in relmap.items():
         relfactor = sum(howmanydict[e] for e in targets)
         howmanydict[str(etype)] = max(relfactor, howmanydict[etype])
     return howmanydict
@@ -1166,7 +1182,7 @@
                 cnx.execute(rql, args)
             except ValidationError as ex:
                 # failed to satisfy some constraint
-                print 'error in automatic db population', ex
+                print('error in automatic db population', ex)
                 cnx.commit_state = None # reset uncommitable flag
         self.post_populate(cnx)
 
@@ -1179,7 +1195,7 @@
                 else:
                     rql = 'Any X WHERE X is %s' % etype
                 rset = req.execute(rql)
-                for row in xrange(len(rset)):
+                for row in range(len(rset)):
                     if limit and row > limit:
                         break
                     # XXX iirk
@@ -1243,7 +1259,10 @@
     tags = AutoPopulateTest.tags | Tags('web', 'generated')
 
     def setUp(self):
-        assert not self.__class__ is AutomaticWebTest, 'Please subclass AutomaticWebTest to prevent database caching issue'
+        if self.__class__ is AutomaticWebTest:
+            # Prevent direct use of AutomaticWebTest to avoid database caching
+            # issues.
+            return
         super(AutomaticWebTest, self).setUp()
 
         # access to self.app for proper initialization of the authentication
@@ -1284,7 +1303,7 @@
 #     # XXX broken
 #     from cubicweb.devtools.apptest import TestEnvironment
 #     env = testclass._env = TestEnvironment('data', configcls=testclass.configcls)
-#     for reg in env.vreg.itervalues():
+#     for reg in env.vreg.values():
 #         reg._selected = {}
 #         try:
 #             orig_select_best = reg.__class__.__orig_select_best
@@ -1304,10 +1323,10 @@
 
 
 # def print_untested_objects(testclass, skipregs=('hooks', 'etypes')):
-#     for regname, reg in testclass._env.vreg.iteritems():
+#     for regname, reg in testclass._env.vreg.items():
 #         if regname in skipregs:
 #             continue
-#         for appobjects in reg.itervalues():
+#         for appobjects in reg.values():
 #             for appobject in appobjects:
 #                 if not reg._selected.get(appobject):
 #                     print 'not tested', regname, appobject
--- a/doc/book/devrepo/fti.rst	Wed Dec 09 18:42:13 2015 +0100
+++ b/doc/book/devrepo/fti.rst	Thu Dec 10 12:34:15 2015 +0100
@@ -94,37 +94,10 @@
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 ``db-rebuild-fti`` will call the
-:meth:`~cubicweb.entities.AnyEntity.cw_fti_index_rql_queries` class
+:meth:`~cubicweb.entities.AnyEntity.cw_fti_index_rql_limit` class
 method on your entity type.
 
-.. automethod:: cubicweb.entities.AnyEntity.cw_fti_index_rql_queries
-
-Now, suppose you've got a _huge_ table to index, you probably don't want to
-get all entities at once. So here's a simple customized example that will
-process block of 10000 entities:
-
-.. sourcecode:: python
-
-
-    class MyEntityClass(AnyEntity):
-        __regid__ = 'MyEntityClass'
-
-    @classmethod
-    def cw_fti_index_rql_queries(cls, req):
-        # get the default RQL method and insert LIMIT / OFFSET instructions
-        base_rql = super(SearchIndex, cls).cw_fti_index_rql_queries(req)[0]
-        selected, restrictions = base_rql.split(' WHERE ')
-        rql_template = '%s ORDERBY X LIMIT %%(limit)s OFFSET %%(offset)s WHERE %s' % (
-            selected, restrictions)
-        # count how many entities you'll have to index
-        count = req.execute('Any COUNT(X) WHERE X is MyEntityClass')[0][0]
-        # iterate by blocks of 10000 entities
-        chunksize = 10000
-        for offset in xrange(0, count, chunksize):
-            print 'SENDING', rql_template % {'limit': chunksize, 'offset': offset}
-            yield rql_template % {'limit': chunksize, 'offset': offset}
-
-Since you have access to ``req``, you can more or less fetch whatever you want.
+.. automethod:: cubicweb.entities.AnyEntity.cw_fti_index_rql_limit
 
 
 Customizing :meth:`~cubicweb.entities.adapters.IFTIndexableAdapter.get_words`
--- a/doc/book/devrepo/testing.rst	Wed Dec 09 18:42:13 2015 +0100
+++ b/doc/book/devrepo/testing.rst	Thu Dec 10 12:34:15 2015 +0100
@@ -324,9 +324,9 @@
 
         def test_blog_rss(self):
             with self.admin_access.web_request() as req:
-            rset = req.execute('Any B ORDERBY D DESC WHERE B is BlogEntry, '
-                               'B created_by U, U login "logilab", B creation_date D')
-            self.view('rss', rset, req=req)
+                rset = req.execute('Any B ORDERBY D DESC WHERE B is BlogEntry, '
+                                   'B created_by U, U login "logilab", B creation_date D')
+                self.view('rss', rset, req=req)
 
 
 Testing with other cubes
--- a/doc/book/devweb/views/table.rst	Wed Dec 09 18:42:13 2015 +0100
+++ b/doc/book/devweb/views/table.rst	Thu Dec 10 12:34:15 2015 +0100
@@ -96,8 +96,8 @@
             'resource': MainEntityColRenderer(),
             'workpackage': EntityTableColRenderer(
                header='Workpackage',
-               renderfunc=worpackage_cell,
-               sortfunc=worpackage_sortvalue,),
+               renderfunc=workpackage_cell,
+               sortfunc=workpackage_sortvalue,),
             'in_state': EntityTableColRenderer(
                renderfunc=lambda w,x: w(x.cw_adapt_to('IWorkflowable').printable_state),
                sortfunc=lambda x: x.cw_adapt_to('IWorkflowable').printable_state),
--- a/doc/changes/3.21.rst	Wed Dec 09 18:42:13 2015 +0100
+++ b/doc/changes/3.21.rst	Thu Dec 10 12:34:15 2015 +0100
@@ -1,5 +1,5 @@
-3.21
-====
+3.21 (10 July 2015)
+===================
 
 New features
 ------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/changes/3.22.rst	Thu Dec 10 12:34:15 2015 +0100
@@ -0,0 +1,71 @@
+3.22
+====
+
+New features
+------------
+
+* a huge amount of changes were done towards python 3.x support (as yet
+  incomplete).  This introduces a new dependency on six, to handle
+  python2/python3 compatibility.
+
+* new cubicweb.dataimport.massive_store module, a postgresql-specific store
+  using the COPY statement to accelerate massive data imports.  This
+  functionality was previously part of cubicweb-dataio (there are some API
+  differences with that previous version, however).
+
+* cubes custom sql scripts are executed before creating tables.  This allows
+  them to create new types or extensions.
+
+User-visible changes
+--------------------
+
+* the ldapfeed source now depends on the `ldap3` module instead of
+  `python-ldap`.
+
+* replies don't get an ``Expires`` header by default.  However when they do,
+  they also get a coherent ``Cache-Control``.
+
+* data files are regenerated at each request, they are no longer cached by
+  ``cubicweb.web.PropertySheet``.  Requests for data files missing the instance
+  hash are handled with a redirection instead of a direct reply, to allow
+  correct cache-related reply headers.
+
+API changes
+-----------
+
+* ``config.repository()`` creates a new Repository object each time, instead of
+  returning a cached object
+
+* migration scripts, as well as other scripts executed by ``cubicweb-ctl
+  shell``, are loaded with the print_function flag enabled (for backwards
+  compatibility, if that fails they are re-loaded without that flag)
+
+* the ``cw_fti_index_rql_queries`` method on entity classes is replaced by
+  ``cw_fti_index_rql_limit``, a generator which yields ``ResultSet`` objects
+  containing entities to be indexed.  By default, entities are returned 1000 at
+  a time.
+
+* ``IDownloadableAdapter`` API is clarified: ``download_url``,
+  ``download_content_type`` and ``download_file_name`` return unicode objects,
+  ``download_data`` returns bytes.
+
+* the ``Repository.extid2eid()`` entry point for external sources is deprecated.
+  Imports should use one of the stores from the ``cubicweb.dataimport`` package
+  instead.
+
+* the ``cubicweb.repoapi.get_repository()`` function's ``uri`` argument should
+  no longer be used.
+
+* the generic datafeed xml parser is deprecated in favor of the "store" API
+  introduced in cubicweb 3.21.
+
+* the session manager lives in the ``sessions`` registry instead of ``components``.
+
+Deprecated code drops
+---------------------
+
+* the ``cubicweb.server.hooksmanager`` module was removed
+
+* the ``Repository.pinfo()`` method was removed
+
+* the ``cubicweb.utils.SizeConstrainedList`` class was removed
--- a/doc/changes/changelog.rst	Wed Dec 09 18:42:13 2015 +0100
+++ b/doc/changes/changelog.rst	Thu Dec 10 12:34:15 2015 +0100
@@ -2,6 +2,7 @@
  Changelog history
 ===================
 
+.. include:: 3.22.rst
 .. include:: 3.21.rst
 .. include:: 3.20.rst
 .. include:: 3.19.rst
--- a/doc/changes/index.rst	Wed Dec 09 18:42:13 2015 +0100
+++ b/doc/changes/index.rst	Thu Dec 10 12:34:15 2015 +0100
@@ -4,6 +4,7 @@
 .. toctree::
     :maxdepth: 1
 
+    3.22
     3.21
     3.20
     3.19
--- a/doc/dev/features_list.rst	Wed Dec 09 18:42:13 2015 +0100
+++ b/doc/dev/features_list.rst	Thu Dec 10 12:34:15 2015 +0100
@@ -2,21 +2,21 @@
 CubicWeb features
 =================
 
-This page  tries to resume features found in the bare cubicweb framework,
+This page summarizes features found in the bare cubicweb framework and indicates
 how mature and documented they are.
 
 :code maturity (CM):
 
   - 0: experimental, not ready at all for production, may be killed
 
-  - 1: draft / unsatisfying, api may change in a near future, much probably in long
-       term
+  - 1: draft / unsatisfying, API may change in a near future, and will
+    certainly change in the long term
 
-  - 2: good enough, api sounds good but will probably evolve a bit with more
+  - 2: good enough, API sounds good but will probably evolve a bit with more
     hindsight
 
-  - 3: mature, backward incompatible changes unexpected (may still evolve though,
-    of course)
+  - 3: mature, backward incompatible changes unexpected (may still evolve
+    though, of course)
 
 
 :documentation level (DL):
@@ -25,7 +25,7 @@
 
   - 1: poor documentation
 
-  - 2: some valuable documentation but some parts keep uncovered
+  - 2: some valuable documentation but incomplete coverage
 
   - 3: good / complete documentation
 
@@ -33,191 +33,306 @@
 Instance configuration and maintainance
 =======================================
 
-+====================================================================+====+====+
-|  FEATURE                                                           | CM | DL |
-+====================================================================+====+====+
-| setup - installation                                               | 2  | 3  |
-| setup - environment variables                                      | 3  | 2  |
-| setup - running modes                                              | 2  | 2  |
-| setup - administration tasks                                       | 2  | 2  |
-| setup - configuration file                                         | 2  | 1  |
-+--------------------------------------------------------------------+----+----+
-| configuration - user / groups handling                             | 3  | 1  |
-| configuration - site configuration                                 | 3  | 1  |
-| configuration - distributed configuration                          | 2  | 1  |
-+--------------------------------------------------------------------+----+----+
-| multi-sources - capabilities                                       | NA | 0  |
-| multi-sources - configuration                                      | 2  | 0  |
-| multi-sources - ldap integration                                   | 2  | 1  |
-+--------------------------------------------------------------------+----+----+
-| usage - custom ReST markup                                         | 2  | 0  |
-| usage - personal preferences                                       | 2  | 1  |
-+--------------------------------------------------------------------+----+----+
+.. table::
 
+   +-------------------------------------------------------------------+----+----+
+   |  FEATURE                                                          | CM | DL |
+   +===============+===================================================+====+====+
+   |    setup      | installation                                      | 2  | 3  |
+   |               +---------------------------------------------------+----+----+
+   |               | environment variables                             | 3  | 2  |
+   |               +---------------------------------------------------+----+----+
+   |               | running modes                                     | 2  | 2  |
+   |               +---------------------------------------------------+----+----+
+   |               | administration tasks                              | 2  | 2  |
+   |               +---------------------------------------------------+----+----+
+   |               | configuration file                                | 2  | 1  |
+   +---------------+---------------------------------------------------+----+----+
+   | configuration | user / groups handling                            | 3  | 1  |
+   |               +---------------------------------------------------+----+----+
+   |               | site configuration                                | 3  | 1  |
+   |               +---------------------------------------------------+----+----+
+   |               | distributed configuration                         | 2  | 1  |
+   +---------------+---------------------------------------------------+----+----+
+   | multi-sources | capabilities                                      | NA | 0  |
+   |               +---------------------------------------------------+----+----+
+   |               | configuration                                     | 2  | 0  |
+   |               +---------------------------------------------------+----+----+
+   |               | ldap integration                                  | 2  | 1  |
+   +---------------+---------------------------------------------------+----+----+
+   | usage         | custom ReST markup                                | 2  | 0  |
+   |               +---------------------------------------------------+----+----+
+   |               | personal preferences                              | 2  | 1  |
+   +---------------+---------------------------------------------------+----+----+
 
 Core development
 ================
 
-+====================================================================+====+====+
-|  FEATURE                                                           | CM | DL |
-+====================================================================+====+====+
-| base - concepts                                                    | NA | 3  |
-| base - security model                                              | NA | 2  |
-| base - database initialization                                     | 2  | 1  |
-+--------------------------------------------------------------------+----+----+
-| rql - base                                                         | 2  | 2  |
-| rql - write                                                        | 2  | 2  |
-| rql - function                                                     | 2  | 0  |
-| rql - outer joins                                                  | 2  | 1  |
-| rql - aggregates                                                   | 2  | 1  |
-| rql - subqueries                                                   | 2  | 0  |
-+--------------------------------------------------------------------+----+----+
-| schema - base                                                      | 2  | 3  |
-| schema - constraints                                               | 3  | 2  |
-| schema - security                                                  | 2  | 2  |
-| schema - inheritance                                               | 1  | 1  |
-| schema - customization                                             | 1  | 1  |
-| schema - introspection                                             | 2  | 1  |
-+--------------------------------------------------------------------+----+----+
-| vregistry - appobject                                              | 2  | 2  |
-| vregistry - registration                                           | 2  | 2  |
-| vregistry - selection                                              | 3  | 2  |
-| vregistry - core selectors                                         | 3  | 3  |
-| vregistry - custom selectors                                       | 2  | 1  |
-| vregistry - debugging selection                                    | 2  | 1  |
-+--------------------------------------------------------------------+----+----+
-| entities - interfaces                                              | 2  | ?  |
-| entities - customization (`dc_`, ...)                              | 2  | ?  |
-| entities - app logic                                               | 2  | 2  |
-| entities - orm configuration                                       | 2  | 1  |
-| entities - pluggable mixins                                        | 1  | 0  |
-| entities - workflow                                                | 3  | 2  |
-+--------------------------------------------------------------------+----+----+
-| dbapi - connection                                                 | 3  | 1  |
-| dbapi - data management                                            | 1  | 1  |
-| dbapi - result set                                                 | 3  | 1  |
-| dbapi - transaction, undo                                          | 2  | 0  |
-+--------------------------------------------------------------------+----+----+
-| cube - layout                                                      | 2  | 3  |
-| cube - new cube                                                    | 2  | 2  |
-+--------------------------------------------------------------------+----+----+
-| migration - context                                                | 2  | 1  |
-| migration - commands                                               | 2  | 2  |
-+--------------------------------------------------------------------+----+----+
-| testlib - CubicWebTC                                               | 2  | 1  |
-| testlib - automatic tests                                          | 2  | 2  |
-+--------------------------------------------------------------------+----+----+
-| i18n - mark string                                                 | 3  | 2  |
-| i18n - customize strings from other cubes / cubicweb               | 3  | 1  |
-| i18n - update catalog                                              | 3  | 2  |
-+--------------------------------------------------------------------+----+----+
-| more - reloading tips                                              | NA | 0  |
-| more - site_cubicweb                                               | 2  | ?  |
-| more - adding options in configuration file                        | 3  | 0  |
-| more - adding options in site configuration / preferences          | 3  | ?  |
-| more - optimizing / profiling                                      | 2  | 1  |
-| more - c-c plugins                                                 | 3  | 0  |
-| more - crypto services                                             | 0  | 0  |
-| more - massive import                                              | 2  | 0  |
-| more - mime type based conversion                                  | 2  | 0  |
-| more - CWCache                                                     | 1  | 0  |
-+--------------------------------------------------------------------+----+----+
+.. table::
+
+   +--------------------------------------------------------------------+----+----+
+   |  FEATURE                                                           | CM | DL |
+   +===========+========================================================+====+====+
+   | base      | concepts                                               | NA | 3  |
+   |           +--------------------------------------------------------+----+----+
+   |           | security model                                         | NA | 2  |
+   |           +--------------------------------------------------------+----+----+
+   |           | database initialization                                | 2  | 1  |
+   +-----------+--------------------------------------------------------+----+----+
+   | rql       | base                                                   | 2  | 2  |
+   |           +--------------------------------------------------------+----+----+
+   |           | write                                                  | 2  | 2  |
+   |           +--------------------------------------------------------+----+----+
+   |           | function                                               | 2  | 0  |
+   |           +--------------------------------------------------------+----+----+
+   |           | outer joins                                            | 2  | 1  |
+   |           +--------------------------------------------------------+----+----+
+   |           | aggregates                                             | 2  | 1  |
+   |           +--------------------------------------------------------+----+----+
+   |           | subqueries                                             | 2  | 0  |
+   +-----------+--------------------------------------------------------+----+----+
+   | schema    | base                                                   | 2  | 3  |
+   |           +--------------------------------------------------------+----+----+
+   |           | constraints                                            | 3  | 2  |
+   |           +--------------------------------------------------------+----+----+
+   |           | security                                               | 2  | 2  |
+   |           +--------------------------------------------------------+----+----+
+   |           | inheritance                                            | 1  | 1  |
+   |           +--------------------------------------------------------+----+----+
+   |           | customization                                          | 1  | 1  |
+   |           +--------------------------------------------------------+----+----+
+   |           | introspection                                          | 2  | 1  |
+   +-----------+--------------------------------------------------------+----+----+
+   | vregistry | appobject                                              | 2  | 2  |
+   |           +--------------------------------------------------------+----+----+
+   |           | registration                                           | 2  | 2  |
+   |           +--------------------------------------------------------+----+----+
+   |           | selection                                              | 3  | 2  |
+   |           +--------------------------------------------------------+----+----+
+   |           | core selectors                                         | 3  | 3  |
+   |           +--------------------------------------------------------+----+----+
+   |           | custom selectors                                       | 2  | 1  |
+   |           +--------------------------------------------------------+----+----+
+   |           | debugging selection                                    | 2  | 1  |
+   +-----------+--------------------------------------------------------+----+----+
+   | entities  | interfaces                                             | 2  | ?  |
+   |           +--------------------------------------------------------+----+----+
+   |           | customization (`dc_`, ...)                             | 2  | ?  |
+   |           +--------------------------------------------------------+----+----+
+   |           | app logic                                              | 2  | 2  |
+   |           +--------------------------------------------------------+----+----+
+   |           | orm configuration                                      | 2  | 1  |
+   |           +--------------------------------------------------------+----+----+
+   |           | pluggable mixins                                       | 1  | 0  |
+   |           +--------------------------------------------------------+----+----+
+   |           | workflow                                               | 3  | 2  |
+   +-----------+--------------------------------------------------------+----+----+
+   | dbapi     | connection                                             | 3  | 1  |
+   |           +--------------------------------------------------------+----+----+
+   |           | data management                                        | 1  | 1  |
+   |           +--------------------------------------------------------+----+----+
+   |           | result set                                             | 3  | 1  |
+   |           +--------------------------------------------------------+----+----+
+   |           | transaction, undo                                      | 2  | 0  |
+   +-----------+--------------------------------------------------------+----+----+
+   | cube      | layout                                                 | 2  | 3  |
+   |           +--------------------------------------------------------+----+----+
+   |           | new cube                                               | 2  | 2  |
+   +-----------+--------------------------------------------------------+----+----+
+   | migration | context                                                | 2  | 1  |
+   |           +--------------------------------------------------------+----+----+
+   |           | commands                                               | 2  | 2  |
+   +-----------+--------------------------------------------------------+----+----+
+   | testlib   | CubicWebTC                                             | 2  | 1  |
+   |           +--------------------------------------------------------+----+----+
+   |           | automatic tests                                        | 2  | 2  |
+   +-----------+--------------------------------------------------------+----+----+
+   | i18n      | mark string                                            | 3  | 2  |
+   |           +--------------------------------------------------------+----+----+
+   |           | customize strings from other cubes / cubicweb          | 3  | 1  |
+   |           +--------------------------------------------------------+----+----+
+   |           | update catalog                                         | 3  | 2  |
+   +-----------+--------------------------------------------------------+----+----+
+   | more      | reloading tips                                         | NA | 0  |
+   |           +--------------------------------------------------------+----+----+
+   |           | site_cubicweb                                          | 2  | ?  |
+   |           +--------------------------------------------------------+----+----+
+   |           | adding options in configuration file                   | 3  | 0  |
+   |           +--------------------------------------------------------+----+----+
+   |           | adding options in site configuration / preferences     | 3  | ?  |
+   |           +--------------------------------------------------------+----+----+
+   |           | optimizing / profiling                                 | 2  | 1  |
+   |           +--------------------------------------------------------+----+----+
+   |           | c-c plugins                                            | 3  | 0  |
+   |           +--------------------------------------------------------+----+----+
+   |           | crypto services                                        | 0  | 0  |
+   |           +--------------------------------------------------------+----+----+
+   |           | massive import                                         | 2  | 0  |
+   |           +--------------------------------------------------------+----+----+
+   |           | mime type based conversion                             | 2  | 0  |
+   |           +--------------------------------------------------------+----+----+
+   |           | CWCache                                                | 1  | 0  |
+   +-----------+--------------------------------------------------------+----+----+
 
 
 Web UI development
 ==================
 
-+====================================================================+====+====+
-|  FEATURE                                                           | CM | DL |
-+====================================================================+====+====+
-| base - web request                                                 | 2  | 2  |
-| base - exceptions                                                  | 2  | 0  |
-| base - session, authentication                                     | 1  | 0  |
-| base - http caching                                                | 2  | 1  |
-| base - external resources                                          | 2  | 2  |
-| base - static files                                                | 2  | ?  |
-| base - data sharing                                                | 2  | 2  |
-| base - graphical chart customization                               | 1  | 1  |
-+--------------------------------------------------------------------+----+----+
-| publishing - cycle                                                 | 2  | 2  |
-| publishing - error handling                                        | 2  | 1  |
-| publishing - transactions                                          | NA | ?  |
-+--------------------------------------------------------------------+----+----+
-| controller - base                                                  | 2  | 2  |
-| controller - view                                                  | 2  | 1  |
-| controller - edit                                                  | 2  | 1  |
-| controller - json                                                  | 2  | 1  |
-+--------------------------------------------------------------------+----+----+
-| views - base                                                       | 2  | 2  |
-| views - templates                                                  | 2  | 2  |
-| views - boxes                                                      | 2  | 1  |
-| views - components                                                 | 2  | 1  |
-| views - primary                                                    | 2  | 1  |
-| views - tabs                                                       | 2  | 1  |
-| views - xml                                                        | 2  | 0  |
-| views - text                                                       | 2  | 1  |
-| views - table                                                      | 2  | 1  |
-| views - plot                                                       | 2  | 0  |
-| views - navigation                                                 | 2  | 0  |
-| views - calendar, timeline                                         | 2  | 0  |
-| views - index                                                      | 2  | 2  |
-| views - breadcrumbs                                                | 2  | 1  |
-| views - actions                                                    | 2  | 1  |
-| views - debugging                                                  | 2  | 1  |
-+--------------------------------------------------------------------+----+----+
-| form - base                                                        | 2  | 1  |
-| form - fields                                                      | 2  | 1  |
-| form - widgets                                                     | 2  | 1  |
-| form - captcha                                                     | 2  | 0  |
-| form - renderers                                                   | 2  | 0  |
-| form - validation error handling                                   | 2  | 0  |
-| form - autoform                                                    | 2  | 2  |
-| form - reledit                                                     | 2  | 0  |
-+--------------------------------------------------------------------+----+----+
-| facets - base                                                      | 2  | ?  |
-| facets - configuration                                             | 2  | 1  |
-| facets - custom facets                                             | 2  | 0  |
-+--------------------------------------------------------------------+----+----+
-| css - base                                                         | 1  | 1  |
-| css - customization                                                | 1  | 1  |
-+--------------------------------------------------------------------+----+----+
-| js - base                                                          | 1  | 1  |
-| js - jquery                                                        | 1  | 1  |
-| js - base functions                                                | 1  | 0  |
-| js - ajax                                                          | 1  | 0  |
-| js - widgets                                                       | 1  | 1  |
-+--------------------------------------------------------------------+----+----+
-| other - page template                                              | 0  | 0  |
-| other - inline doc (wdoc)                                          | 2  | 0  |
-| other - magic search                                               | 2  | 0  |
-| other - url mapping                                                | 1  | 1  |
-| other - apache style url rewrite                                   | 1  | 1  |
-| other - sparql                                                     | 1  | 0  |
-| other - bookmarks                                                  | 2  | 1  |
-+--------------------------------------------------------------------+----+----+
+.. table::
+
+   +--------------------------------------------------------------------+----+----+
+   |  FEATURE                                                           | CM | DL |
+   +============+=======================================================+====+====+
+   | base       | web request                                           | 2  | 2  |
+   |            +-------------------------------------------------------+----+----+
+   |            | exceptions                                            | 2  | 0  |
+   |            +-------------------------------------------------------+----+----+
+   |            | session, authentication                               | 1  | 0  |
+   |            +-------------------------------------------------------+----+----+
+   |            | http caching                                          | 2  | 1  |
+   |            +-------------------------------------------------------+----+----+
+   |            | external resources                                    | 2  | 2  |
+   |            +-------------------------------------------------------+----+----+
+   |            | static files                                          | 2  | ?  |
+   |            +-------------------------------------------------------+----+----+
+   |            | data sharing                                          | 2  | 2  |
+   |            +-------------------------------------------------------+----+----+
+   |            | graphical chart customization                         | 1  | 1  |
+   +------------+-------------------------------------------------------+----+----+
+   | publishing | cycle                                                 | 2  | 2  |
+   |            +-------------------------------------------------------+----+----+
+   |            | error handling                                        | 2  | 1  |
+   |            +-------------------------------------------------------+----+----+
+   |            | transactions                                          | NA | ?  |
+   +------------+-------------------------------------------------------+----+----+
+   | controller | base                                                  | 2  | 2  |
+   |            +-------------------------------------------------------+----+----+
+   |            | view                                                  | 2  | 1  |
+   |            +-------------------------------------------------------+----+----+
+   |            | edit                                                  | 2  | 1  |
+   |            +-------------------------------------------------------+----+----+
+   |            | json                                                  | 2  | 1  |
+   +------------+-------------------------------------------------------+----+----+
+   | views      | base                                                  | 2  | 2  |
+   |            +-------------------------------------------------------+----+----+
+   |            | templates                                             | 2  | 2  |
+   |            +-------------------------------------------------------+----+----+
+   |            | boxes                                                 | 2  | 1  |
+   |            +-------------------------------------------------------+----+----+
+   |            | components                                            | 2  | 1  |
+   |            +-------------------------------------------------------+----+----+
+   |            | primary                                               | 2  | 1  |
+   |            +-------------------------------------------------------+----+----+
+   |            | tabs                                                  | 2  | 1  |
+   |            +-------------------------------------------------------+----+----+
+   |            | xml                                                   | 2  | 0  |
+   |            +-------------------------------------------------------+----+----+
+   |            | text                                                  | 2  | 1  |
+   |            +-------------------------------------------------------+----+----+
+   |            | table                                                 | 2  | 1  |
+   |            +-------------------------------------------------------+----+----+
+   |            | plot                                                  | 2  | 0  |
+   |            +-------------------------------------------------------+----+----+
+   |            | navigation                                            | 2  | 0  |
+   |            +-------------------------------------------------------+----+----+
+   |            | calendar, timeline                                    | 2  | 0  |
+   |            +-------------------------------------------------------+----+----+
+   |            | index                                                 | 2  | 2  |
+   |            +-------------------------------------------------------+----+----+
+   |            | breadcrumbs                                           | 2  | 1  |
+   |            +-------------------------------------------------------+----+----+
+   |            | actions                                               | 2  | 1  |
+   |            +-------------------------------------------------------+----+----+
+   |            | debugging                                             | 2  | 1  |
+   +------------+-------------------------------------------------------+----+----+
+   | form       | base                                                  | 2  | 1  |
+   |            +-------------------------------------------------------+----+----+
+   |            | fields                                                | 2  | 1  |
+   |            +-------------------------------------------------------+----+----+
+   |            | widgets                                               | 2  | 1  |
+   |            +-------------------------------------------------------+----+----+
+   |            | captcha                                               | 2  | 0  |
+   |            +-------------------------------------------------------+----+----+
+   |            | renderers                                             | 2  | 0  |
+   |            +-------------------------------------------------------+----+----+
+   |            | validation error handling                             | 2  | 0  |
+   |            +-------------------------------------------------------+----+----+
+   |            | autoform                                              | 2  | 2  |
+   |            +-------------------------------------------------------+----+----+
+   |            | reledit                                               | 2  | 0  |
+   +------------+-------------------------------------------------------+----+----+
+   | facets     | base                                                  | 2  | ?  |
+   |            +-------------------------------------------------------+----+----+
+   |            | configuration                                         | 2  | 1  |
+   |            +-------------------------------------------------------+----+----+
+   |            | custom facets                                         | 2  | 0  |
+   +------------+-------------------------------------------------------+----+----+
+   | css        | base                                                  | 1  | 1  |
+   |            +-------------------------------------------------------+----+----+
+   |            | customization                                         | 1  | 1  |
+   +------------+-------------------------------------------------------+----+----+
+   | js         | base                                                  | 1  | 1  |
+   |            +-------------------------------------------------------+----+----+
+   |            | jquery                                                | 1  | 1  |
+   |            +-------------------------------------------------------+----+----+
+   |            | base functions                                        | 1  | 0  |
+   |            +-------------------------------------------------------+----+----+
+   |            | widgets                                               | 1  | 1  |
+   |            +-------------------------------------------------------+----+----+
+   |            | ajax                                                  | 1  | 0  |
+   |            +-------------------------------------------------------+----+----+
+   |            | widgets                                               | 1  | 1  |
+   +------------+-------------------------------------------------------+----+----+
+   | other      | page template                                         | 0  | 0  |
+   |            +-------------------------------------------------------+----+----+
+   |            | inline doc (wdoc)                                     | 2  | 0  |
+   |            +-------------------------------------------------------+----+----+
+   |            | magic search                                          | 2  | 0  |
+   |            +-------------------------------------------------------+----+----+
+   |            | url mapping                                           | 1  | 1  |
+   |            +-------------------------------------------------------+----+----+
+   |            | apache style url rewrite                              | 1  | 1  |
+   |            +-------------------------------------------------------+----+----+
+   |            | sparql                                                | 1  | 0  |
+   |            +-------------------------------------------------------+----+----+
+   |            | bookmarks                                             | 2  | 1  |
+   +------------+-------------------------------------------------------+----+----+
 
 
 Repository development
 ======================
 
-+====================================================================+====+====+
-|  FEATURE                                                           | CM | DL |
-+====================================================================+====+====+
-| base - session                                                     | 2  | 2  |
-| base - more security control                                       | 2  | 0  |
-| base - debugging                                                   | 2  | 0  |
-+--------------------------------------------------------------------+----+----+
-| hooks - development                                                | 2  | 2  |
-| hooks - abstract hooks                                             | 2  | 0  |
-| hooks - core hooks                                                 | 2  | 0  |
-| hooks - control                                                    | 2  | 0  |
-| hooks - operation                                                  | 2  | 2  |
-+--------------------------------------------------------------------+----+----+
-| notification - sending email                                       | 2  | ?  |
-| notification - base views                                          | 1  | ?  |
-| notification - supervisions                                        | 1  | 0  |
-+--------------------------------------------------------------------+----+----+
-| source - storages                                                  | 2  | 0  |
-| source - authentication plugins                                    | 2  | 0  |
-| source - custom sources                                            | 2  | 0  |
-+--------------------------------------------------------------------+----+----+
+.. table::
+
+   +--------------------------------------------------------------------+----+----+
+   |  FEATURE                                                           | CM | DL |
+   +==============+=====================================================+====+====+
+   | base         | session                                             | 2  | 2  |
+   |              +-----------------------------------------------------+----+----+
+   |              | more security control                               | 2  | 0  |
+   |              +-----------------------------------------------------+----+----+
+   |              | debugging                                           | 2  | 0  |
+   +--------------+-----------------------------------------------------+----+----+
+   | hooks        | development                                         | 2  | 2  |
+   |              +-----------------------------------------------------+----+----+
+   |              | abstract hooks                                      | 2  | 0  |
+   |              +-----------------------------------------------------+----+----+
+   |              | core hooks                                          | 2  | 0  |
+   |              +-----------------------------------------------------+----+----+
+   |              | control                                             | 2  | 0  |
+   |              +-----------------------------------------------------+----+----+
+   |              | operation                                           | 2  | 2  |
+   +--------------+-----------------------------------------------------+----+----+
+   | notification | sending email                                       | 2  | ?  |
+   |              +-----------------------------------------------------+----+----+
+   |              | base views                                          | 1  | ?  |
+   |              +-----------------------------------------------------+----+----+
+   |              | supervisions                                        | 1  | 0  |
+   +--------------+-----------------------------------------------------+----+----+
+   | source       | storages                                            | 2  | 0  |
+   |              +-----------------------------------------------------+----+----+
+   |              | authentication plugins                              | 2  | 0  |
+   |              +-----------------------------------------------------+----+----+
+   |              | custom sources                                      | 2  | 0  |
+   +--------------+-----------------------------------------------------+----+----+
+
--- a/doc/tools/mode_plan.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/doc/tools/mode_plan.py	Thu Dec 10 12:34:15 2015 +0100
@@ -23,17 +23,19 @@
 rename A010-joe.en.txt to A030-joe.en.txt
 accept [y/N]?
 """
+from __future__ import print_function
+
 
 def ren(a,b):
     names = glob.glob('%s*'%a)
     for name in names :
-        print 'rename %s to %s' % (name, name.replace(a,b))
+        print('rename %s to %s' % (name, name.replace(a,b)))
     if raw_input('accept [y/N]?').lower() =='y':
         for name in names:
             os.system('hg mv %s %s' % (name, name.replace(a,b)))
 
 
-def ls(): print '\n'.join(sorted(os.listdir('.')))
+def ls(): print('\n'.join(sorted(os.listdir('.'))))
 
 def move():
     filenames = []
@@ -47,4 +49,4 @@
 
     for num, name in filenames:
         if num >= start:
-            print 'hg mv %s %2i%s' %(name,num+1,name[2:])
+            print('hg mv %s %2i%s' %(name,num+1,name[2:]))
--- a/doc/tutorials/base/customizing-the-application.rst	Wed Dec 09 18:42:13 2015 +0100
+++ b/doc/tutorials/base/customizing-the-application.rst	Thu Dec 10 12:34:15 2015 +0100
@@ -422,7 +422,7 @@
           entity = self.cw_rset.get_entity(row, col)
           self.w(u'<h1>Welcome to the "%s" community</h1>' % entity.printable_value('name'))
           if entity.display_cw_logo():
-              self.w(u'<img src="http://www.cubicweb.org/doc/en/_static/cubicweb.png"/>')
+              self.w(u'<img src="https://docs.cubicweb.org/_static/logo-cubicweb-small.svg"/>')
           if entity.description:
               self.w(u'<p>%s</p>' % entity.printable_value('description'))
 
@@ -522,7 +522,7 @@
 
       def render_entity_attributes(self, entity):
 	  if entity.display_cw_logo():
-	      self.w(u'<img src="http://www.cubicweb.org/doc/en/_static/cubicweb.png"/>')
+	      self.w(u'<img src="https://docs.cubicweb.org/_static/logo-cubicweb-small.svg"/>')
 	  if entity.description:
 	      self.w(u'<p>%s</p>' % entity.printable_value('description'))
 
--- a/doc/tutorials/base/discovering-the-ui.rst	Wed Dec 09 18:42:13 2015 +0100
+++ b/doc/tutorials/base/discovering-the-ui.rst	Thu Dec 10 12:34:15 2015 +0100
@@ -101,16 +101,16 @@
 
 You can achieve the same thing by following the same path as we did for the blog
 creation, e.g. by clicking on the `[+]` at the left of the 'Blog entry' link on
-the index page. The diffidence being that since there is no context information,
+the index page. The difference being that since there is no context information,
 the 'blog entry of' selector won't be preset to the blog.
 
 
 If you click on the 'modify' link of the action box, you are back to
 the form to edit the entity you just created, except that the form now
 has another section with a combo-box entitled 'add relation'. It
-provisos a generic way to edit relations which don't appears in the
+provides a generic way to edit relations which don't appears in the
 above form. Choose the relation you want to add and a second combo box
-appears where you can pick existing entities.  If there are too many
+appears where you can pick existing entities. If there are too many
 of them, you will be offered to navigate to the target entity, that is
 go away from the form and go back to it later, once you've selected
 the entity you want to link with.
--- a/doc/tutorials/dataimport/diseasome_import.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/doc/tutorials/dataimport/diseasome_import.py	Thu Dec 10 12:34:15 2015 +0100
@@ -95,7 +95,7 @@
     # Perform a first commit, of the entities
     store.flush()
     kwargs = {}
-    for uri, relations in all_relations.iteritems():
+    for uri, relations in all_relations.items():
         from_eid = uri_to_eid.get(uri)
         # ``subjtype`` should be initialized if ``SQLGenObjectStore`` is used
         # and there are inlined relations in the schema.
@@ -108,7 +108,7 @@
         kwargs['subjtype'] = uri_to_etype.get(uri)
         if not from_eid:
             continue
-        for rtype, rels in relations.iteritems():
+        for rtype, rels in relations.items():
             if rtype in ('classes', 'possible_drugs', 'omim', 'omim_page',
                          'chromosomal_location', 'same_as', 'gene_id',
                          'hgnc_id', 'hgnc_page'):
--- a/doc/tutorials/dataimport/diseasome_parser.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/doc/tutorials/dataimport/diseasome_parser.py	Thu Dec 10 12:34:15 2015 +0100
@@ -97,4 +97,4 @@
             entities[subj]['relations'].setdefault(MAPPING_RELS[rel], set())
             entities[subj]['relations'][MAPPING_RELS[rel]].add(unicode(obj))
     return ((ent.get('attributes'), ent.get('relations')) 
-            for ent in entities.itervalues())
+            for ent in entities.values())
--- a/entities/__init__.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/entities/__init__.py	Thu Dec 10 12:34:15 2015 +0100
@@ -19,8 +19,12 @@
 
 __docformat__ = "restructuredtext en"
 
+from warnings import warn
+
+from six import text_type, string_types
 
 from logilab.common.decorators import classproperty
+from logilab.common.deprecation import deprecated
 
 from cubicweb import Unauthorized
 from cubicweb.entity import Entity
@@ -35,7 +39,7 @@
     @classproperty
     def cw_etype(cls):
         """entity type as a unicode string"""
-        return unicode(cls.__regid__)
+        return text_type(cls.__regid__)
 
     @classmethod
     def cw_create_url(cls, req, **kwargs):
@@ -43,6 +47,7 @@
         return req.build_url('add/%s' % cls.__regid__, **kwargs)
 
     @classmethod
+    @deprecated('[3.22] use cw_fti_index_rql_limit instead')
     def cw_fti_index_rql_queries(cls, req):
         """return the list of rql queries to fetch entities to FT-index
 
@@ -60,6 +65,37 @@
         return ['Any %s WHERE %s' % (', '.join(selected),
                                      ', '.join(restrictions))]
 
+    @classmethod
+    def cw_fti_index_rql_limit(cls, req, limit=1000):
+        """generate rsets of entities to FT-index
+
+        By default, each successive result set is limited to 1000 entities
+        """
+        if cls.cw_fti_index_rql_queries.__func__ != AnyEntity.cw_fti_index_rql_queries.__func__:
+            warn("[3.22] cw_fti_index_rql_queries is replaced by cw_fti_index_rql_limit",
+                 DeprecationWarning)
+            for rql in cls.cw_fti_index_rql_queries(req):
+                yield req.execute(rql)
+            return
+        restrictions = ['X is %s' % cls.__regid__]
+        selected = ['X']
+        start = 0
+        for attrschema in sorted(cls.e_schema.indexable_attributes()):
+            varname = attrschema.type.upper()
+            restrictions.append('X %s %s' % (attrschema, varname))
+            selected.append(varname)
+        while True:
+            q_restrictions = restrictions + ['X eid > %s' % start]
+            rset = req.execute('Any %s ORDERBY X LIMIT %s WHERE %s' %
+                               (', '.join(selected),
+                                limit,
+                                ', '.join(q_restrictions)))
+            if rset:
+                start = rset[-1][0]
+                yield rset
+            else:
+                break
+
     # meta data api ###########################################################
 
     def dc_title(self):
@@ -134,7 +170,7 @@
             return self.dc_title().lower()
         value = self.cw_attr_value(rtype)
         # do not restrict to `unicode` because Bytes will return a `str` value
-        if isinstance(value, basestring):
+        if isinstance(value, string_types):
             return self.printable_value(rtype, format='text/plain').lower()
         return value
 
--- a/entities/adapters.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/entities/adapters.py	Thu Dec 10 12:34:15 2015 +0100
@@ -20,7 +20,7 @@
 """
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from itertools import chain
 from warnings import warn
@@ -162,7 +162,7 @@
         return words
 
 def merge_weight_dict(maindict, newdict):
-    for weight, words in newdict.iteritems():
+    for weight, words in newdict.items():
         maindict.setdefault(weight, []).extend(words)
 
 class IDownloadableAdapter(view.EntityAdapter):
@@ -171,23 +171,25 @@
     __abstract__ = True
 
     def download_url(self, **kwargs): # XXX not really part of this interface
-        """return a URL to download entity's content"""
+        """return a URL to download entity's content
+
+        It should be a unicode object containing url-encoded ASCII."""
         raise NotImplementedError
 
     def download_content_type(self):
-        """return MIME type of the downloadable content"""
+        """return MIME type (unicode) of the downloadable content"""
         raise NotImplementedError
 
     def download_encoding(self):
-        """return encoding of the downloadable content"""
+        """return encoding (unicode) of the downloadable content"""
         raise NotImplementedError
 
     def download_file_name(self):
-        """return file name of the downloadable content"""
+        """return file name (unicode) of the downloadable content"""
         raise NotImplementedError
 
     def download_data(self):
-        """return actual data of the downloadable content"""
+        """return actual data (bytes) of the downloadable content"""
         raise NotImplementedError
 
 # XXX should propose to use two different relations for children/parent
@@ -386,7 +388,7 @@
         for rschema, attrschema in eschema.attribute_definitions():
             rdef = rschema.rdef(eschema, attrschema)
             for constraint in rdef.constraints:
-                if cstrname == 'cstr' + md5(eschema.type + rschema.type + constraint.type() + (constraint.serialize() or '')).hexdigest():
+                if cstrname == 'cstr' + md5((eschema.type + rschema.type + constraint.type() + (constraint.serialize() or '')).encode('ascii')).hexdigest():
                     break
             else:
                 continue
--- a/entities/authobjs.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/entities/authobjs.py	Thu Dec 10 12:34:15 2015 +0100
@@ -19,6 +19,8 @@
 
 __docformat__ = "restructuredtext en"
 
+from six import string_types
+
 from logilab.common.decorators import cached
 
 from cubicweb import Unauthorized
@@ -126,7 +128,7 @@
         :type groups: str or iterable(str)
         :param groups: a group name or an iterable on group names
         """
-        if isinstance(groups, basestring):
+        if isinstance(groups, string_types):
             groups = frozenset((groups,))
         elif isinstance(groups, (tuple, list)):
             groups = frozenset(groups)
--- a/entities/lib.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/entities/lib.py	Thu Dec 10 12:34:15 2015 +0100
@@ -19,9 +19,10 @@
 
 __docformat__ = "restructuredtext en"
 from warnings import warn
+from datetime import datetime
 
-from urlparse import urlsplit, urlunsplit
-from datetime import datetime
+from six.moves import range
+from six.moves.urllib.parse import urlsplit, urlunsplit
 
 from logilab.mtconverter import xml_escape
 
@@ -67,7 +68,7 @@
                                 {'y': self.eid})
         if skipeids is None:
             skipeids = set()
-        for i in xrange(len(rset)):
+        for i in range(len(rset)):
             eid = rset[i][0]
             if eid in skipeids:
                 continue
@@ -146,4 +147,3 @@
         if date:
             return date > self.timestamp
         return False
-
--- a/entities/sources.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/entities/sources.py	Thu Dec 10 12:34:15 2015 +0100
@@ -42,7 +42,7 @@
         cfg.update(config)
         options = SOURCE_TYPES[self.type].options
         sconfig = SourceConfiguration(self._cw.vreg.config, options=options)
-        for opt, val in cfg.iteritems():
+        for opt, val in cfg.items():
             try:
                 sconfig.set_option(opt, val)
             except OptionError:
--- a/entities/test/unittest_base.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/entities/test/unittest_base.py	Thu Dec 10 12:34:15 2015 +0100
@@ -21,6 +21,7 @@
 
 from logilab.common.testlib import unittest_main
 from logilab.common.decorators import clear_cache
+from logilab.common.registry import yes
 
 from cubicweb.devtools.testlib import CubicWebTC
 
@@ -60,16 +61,35 @@
         # XXX move to yams
         self.assertEqual(self.schema['CWUser'].meta_attributes(), {})
         self.assertEqual(dict((str(k), v)
-                              for k, v in self.schema['State'].meta_attributes().iteritems()),
+                              for k, v in self.schema['State'].meta_attributes().items()),
                           {'description_format': ('format', 'description')})
 
     def test_fti_rql_method(self):
+        class EmailAddress(AnyEntity):
+            __regid__ = 'EmailAddress'
+            __select__ = AnyEntity.__select__ & yes(2)
+            @classmethod
+            def cw_fti_index_rql_queries(cls, req):
+                return ['EmailAddress Y']
         with self.admin_access.web_request() as req:
+            req.create_entity('EmailAddress', address=u'foo@bar.com')
             eclass = self.vreg['etypes'].etype_class('EmailAddress')
+            # deprecated
             self.assertEqual(['Any X, ADDRESS, ALIAS WHERE X is EmailAddress, '
                               'X address ADDRESS, X alias ALIAS'],
                              eclass.cw_fti_index_rql_queries(req))
 
+            self.assertEqual(['Any X, ADDRESS, ALIAS ORDERBY X LIMIT 1000 WHERE X is EmailAddress, '
+                              'X address ADDRESS, X alias ALIAS, X eid > 0'],
+                             [rset.rql for rset in eclass.cw_fti_index_rql_limit(req)])
+
+            # test backwards compatibility with custom method
+            with self.temporary_appobjects(EmailAddress):
+                self.vreg['etypes'].clear_caches()
+                eclass = self.vreg['etypes'].etype_class('EmailAddress')
+                self.assertEqual(['EmailAddress Y'],
+                                 [rset.rql for rset in eclass.cw_fti_index_rql_limit(req)])
+
 
 class EmailAddressTC(BaseEntityTC):
 
--- a/entities/test/unittest_wfobjs.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/entities/test/unittest_wfobjs.py	Thu Dec 10 12:34:15 2015 +0100
@@ -107,7 +107,7 @@
 
     def setup_database(self):
         rschema = self.schema['in_state']
-        for rdef in rschema.rdefs.itervalues():
+        for rdef in rschema.rdefs.values():
             self.assertEqual(rdef.cardinality, '1*')
         with self.admin_access.client_cnx() as cnx:
             self.member_eid = self.create_user(cnx, 'member').eid
--- a/entities/wfobjs.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/entities/wfobjs.py	Thu Dec 10 12:34:15 2015 +0100
@@ -21,9 +21,11 @@
 * workflow history (TrInfo)
 * adapter for workflowable entities (IWorkflowableAdapter)
 """
+from __future__ import print_function
 
 __docformat__ = "restructuredtext en"
 
+from six import text_type, string_types
 
 from logilab.common.decorators import cached, clear_cache
 from logilab.common.deprecation import deprecated
@@ -97,7 +99,7 @@
     def transition_by_name(self, trname):
         rset = self._cw.execute('Any T, TN WHERE T name TN, T name %(n)s, '
                                 'T transition_of WF, WF eid %(wf)s',
-                                {'n': unicode(trname), 'wf': self.eid})
+                                {'n': text_type(trname), 'wf': self.eid})
         if rset:
             return rset.get_entity(0, 0)
         return None
@@ -114,7 +116,7 @@
 
     def add_state(self, name, initial=False, **kwargs):
         """add a state to this workflow"""
-        state = self._cw.create_entity('State', name=unicode(name), **kwargs)
+        state = self._cw.create_entity('State', name=text_type(name), **kwargs)
         self._cw.execute('SET S state_of WF WHERE S eid %(s)s, WF eid %(wf)s',
                          {'s': state.eid, 'wf': self.eid})
         if initial:
@@ -126,7 +128,7 @@
 
     def _add_transition(self, trtype, name, fromstates,
                         requiredgroups=(), conditions=(), **kwargs):
-        tr = self._cw.create_entity(trtype, name=unicode(name), **kwargs)
+        tr = self._cw.create_entity(trtype, name=text_type(name), **kwargs)
         self._cw.execute('SET T transition_of WF '
                          'WHERE T eid %(t)s, WF eid %(wf)s',
                          {'t': tr.eid, 'wf': self.eid})
@@ -224,19 +226,19 @@
             matches = user.matching_groups(groups)
             if matches:
                 if DBG:
-                    print 'may_be_fired: %r may fire: user matches %s' % (self.name, groups)
+                    print('may_be_fired: %r may fire: user matches %s' % (self.name, groups))
                 return matches
             if 'owners' in groups and user.owns(eid):
                 if DBG:
-                    print 'may_be_fired: %r may fire: user is owner' % self.name
+                    print('may_be_fired: %r may fire: user is owner' % self.name)
                 return True
         # check one of the rql expression conditions matches if any
         if self.condition:
             if DBG:
-                print ('my_be_fired: %r: %s' %
-                       (self.name, [(rqlexpr.expression,
+                print('my_be_fired: %r: %s' %
+                      (self.name, [(rqlexpr.expression,
                                     rqlexpr.check_expression(self._cw, eid))
-                                   for rqlexpr in self.condition]))
+                                    for rqlexpr in self.condition]))
             for rqlexpr in self.condition:
                 if rqlexpr.check_expression(self._cw, eid):
                     return True
@@ -256,13 +258,13 @@
         for gname in requiredgroups:
             rset = self._cw.execute('SET T require_group G '
                                     'WHERE T eid %(x)s, G name %(gn)s',
-                                    {'x': self.eid, 'gn': unicode(gname)})
+                                    {'x': self.eid, 'gn': text_type(gname)})
             assert rset, '%s is not a known group' % gname
-        if isinstance(conditions, basestring):
+        if isinstance(conditions, string_types):
             conditions = (conditions,)
         for expr in conditions:
-            if isinstance(expr, basestring):
-                kwargs = {'expr': unicode(expr)}
+            if isinstance(expr, string_types):
+                kwargs = {'expr': text_type(expr)}
             else:
                 assert isinstance(expr, dict)
                 kwargs = expr
@@ -414,7 +416,7 @@
         """return the default workflow for entities of this type"""
         # XXX CWEType method
         wfrset = self._cw.execute('Any WF WHERE ET default_workflow WF, '
-                                  'ET name %(et)s', {'et': unicode(self.entity.cw_etype)})
+                                  'ET name %(et)s', {'et': text_type(self.entity.cw_etype)})
         if wfrset:
             return wfrset.get_entity(0, 0)
         self.warning("can't find any workflow for %s", self.entity.cw_etype)
@@ -479,7 +481,7 @@
             'Any T,TT, TN WHERE S allowed_transition T, S eid %(x)s, '
             'T type TT, T type %(type)s, '
             'T name TN, T transition_of WF, WF eid %(wfeid)s',
-            {'x': self.current_state.eid, 'type': unicode(type),
+            {'x': self.current_state.eid, 'type': text_type(type),
              'wfeid': self.current_workflow.eid})
         for tr in rset.entities():
             if tr.may_be_fired(self.entity.eid):
@@ -528,7 +530,7 @@
 
     def _get_transition(self, tr):
         assert self.current_workflow
-        if isinstance(tr, basestring):
+        if isinstance(tr, string_types):
             _tr = self.current_workflow.transition_by_name(tr)
             assert _tr is not None, 'not a %s transition: %s' % (
                 self.__regid__, tr)
@@ -549,7 +551,7 @@
         tr = self._get_transition(tr)
         if any(tr_ for tr_ in self.possible_transitions()
                if tr_.eid == tr.eid):
-            self.fire_transition(tr)
+            self.fire_transition(tr, comment, commentformat)
 
     def change_state(self, statename, comment=None, commentformat=None, tr=None):
         """change the entity's state to the given state (name or entity) in
--- a/entity.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/entity.py	Thu Dec 10 12:34:15 2015 +0100
@@ -22,6 +22,9 @@
 from warnings import warn
 from functools import partial
 
+from six import text_type, string_types, integer_types
+from six.moves import range
+
 from logilab.common.decorators import cached
 from logilab.common.deprecation import deprecated
 from logilab.common.registry import yes
@@ -57,7 +60,7 @@
     """return True if value can be used at the end of a Rest URL path"""
     if value is None:
         return False
-    value = unicode(value)
+    value = text_type(value)
     # the check for ?, /, & are to prevent problems when running
     # behind Apache mod_proxy
     if value == u'' or u'?' in value or u'/' in value or u'&' in value:
@@ -105,7 +108,7 @@
     """
     st = cstr.snippet_rqlst.copy()
     # replace relations in ST by eid infos from linkto where possible
-    for (info_rtype, info_role), eids in lt_infos.iteritems():
+    for (info_rtype, info_role), eids in lt_infos.items():
         eid = eids[0] # NOTE: we currently assume a pruned lt_info with only 1 eid
         for rel in st.iget_nodes(RqlRelation):
             targetvar = rel_matches(rel, info_rtype, info_role, evar.name)
@@ -132,7 +135,7 @@
 
 def pruned_lt_info(eschema, lt_infos):
     pruned = {}
-    for (lt_rtype, lt_role), eids in lt_infos.iteritems():
+    for (lt_rtype, lt_role), eids in lt_infos.items():
         # we can only use lt_infos describing relation with a cardinality
         # of value 1 towards the linked entity
         if not len(eids) == 1:
@@ -144,6 +147,7 @@
         pruned[(lt_rtype, lt_role)] = eids
     return pruned
 
+
 class Entity(AppObject):
     """an entity instance has e_schema automagically set on
     the class and instances has access to their issuing cursor.
@@ -279,7 +283,7 @@
             select = Select()
             mainvar = select.get_variable(mainvar)
             select.add_selected(mainvar)
-        elif isinstance(mainvar, basestring):
+        elif isinstance(mainvar, string_types):
             assert mainvar in select.defined_vars
             mainvar = select.get_variable(mainvar)
         # eases string -> syntax tree test transition: please remove once stable
@@ -455,7 +459,7 @@
                 if len(value) == 0:
                     continue # avoid crash with empty IN clause
                 elif len(value) == 1:
-                    value = iter(value).next()
+                    value = next(iter(value))
                 else:
                     # prepare IN clause
                     pendingrels.append( (attr, role, value) )
@@ -530,6 +534,7 @@
     def __init__(self, req, rset=None, row=None, col=0):
         AppObject.__init__(self, req, rset=rset, row=row, col=col)
         self._cw_related_cache = {}
+        self._cw_adapters_cache = {}
         if rset is not None:
             self.eid = rset[row][col]
         else:
@@ -545,12 +550,12 @@
         raise NotImplementedError('comparison not implemented for %s' % self.__class__)
 
     def __eq__(self, other):
-        if isinstance(self.eid, (int, long)):
+        if isinstance(self.eid, integer_types):
             return self.eid == other.eid
         return self is other
 
     def __hash__(self):
-        if isinstance(self.eid, (int, long)):
+        if isinstance(self.eid, integer_types):
             return self.eid
         return super(Entity, self).__hash__()
 
@@ -567,10 +572,7 @@
 
         return None if it can not be adapted.
         """
-        try:
-            cache = self._cw_adapters_cache
-        except AttributeError:
-            self._cw_adapters_cache = cache = {}
+        cache = self._cw_adapters_cache
         try:
             return cache[interface]
         except KeyError:
@@ -677,8 +679,8 @@
         if path is None:
             # fallback url: <base-url>/<eid> url is used as cw entities uri,
             # prefer it to <base-url>/<etype>/eid/<eid>
-            return unicode(value)
-        return '%s/%s' % (path, self._cw.url_quote(value))
+            return text_type(value)
+        return u'%s/%s' % (path, self._cw.url_quote(value))
 
     def cw_attr_metadata(self, attr, metadata):
         """return a metadata for an attribute (None if unspecified)"""
@@ -695,7 +697,7 @@
         attr = str(attr)
         if value is _marker:
             value = getattr(self, attr)
-        if isinstance(value, basestring):
+        if isinstance(value, string_types):
             value = value.strip()
         if value is None or value == '': # don't use "not", 0 is an acceptable value
             return u''
@@ -849,7 +851,7 @@
         if attributes is None:
             self._cw_completed = True
         varmaker = rqlvar_maker()
-        V = varmaker.next()
+        V = next(varmaker)
         rql = ['WHERE %s eid %%(x)s' % V]
         selected = []
         for attr in (attributes or self._cw_to_complete_attributes(skip_bytes, skip_pwd)):
@@ -857,7 +859,7 @@
             if attr in self.cw_attr_cache:
                 continue
             # case where attribute must be completed, but is not yet in entity
-            var = varmaker.next()
+            var = next(varmaker)
             rql.append('%s %s %s' % (V, attr, var))
             selected.append((attr, var))
         # +1 since this doesn't include the main variable
@@ -876,7 +878,7 @@
                 # * user has read perm on the relation and on the target entity
                 assert rschema.inlined
                 assert role == 'subject'
-                var = varmaker.next()
+                var = next(varmaker)
                 # keep outer join anyway, we don't want .complete to crash on
                 # missing mandatory relation (see #1058267)
                 rql.append('%s %s %s?' % (V, rtype, var))
@@ -892,10 +894,10 @@
                 raise Exception('unable to fetch attributes for entity with eid %s'
                                 % self.eid)
             # handle attributes
-            for i in xrange(1, lastattr):
+            for i in range(1, lastattr):
                 self.cw_attr_cache[str(selected[i-1][0])] = rset[i]
             # handle relations
-            for i in xrange(lastattr, len(rset)):
+            for i in range(lastattr, len(rset)):
                 rtype, role = selected[i-1][0]
                 value = rset[i]
                 if value is None:
@@ -1145,9 +1147,7 @@
         self._cw.vreg.solutions(self._cw, select, args)
         # insert RQL expressions for schema constraints into the rql syntax tree
         if vocabconstraints:
-            # RQLConstraint is a subclass for RQLVocabularyConstraint, so they
-            # will be included as well
-            cstrcls = RQLVocabularyConstraint
+            cstrcls = (RQLVocabularyConstraint, RQLConstraint)
         else:
             cstrcls = RQLConstraint
         lt_infos = pruned_lt_info(self.e_schema, lt_infos or {})
@@ -1236,8 +1236,8 @@
         no relation is given
         """
         if rtype is None:
-            self._cw_related_cache = {}
-            self._cw_adapters_cache = {}
+            self._cw_related_cache.clear()
+            self._cw_adapters_cache.clear()
         else:
             assert role
             self._cw_related_cache.pop('%s_%s' % (rtype, role), None)
--- a/etwist/__init__.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/etwist/__init__.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,4 +18,3 @@
 """ CW - nevow/twisted client
 
 """
-
--- a/etwist/request.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/etwist/request.py	Thu Dec 10 12:34:15 2015 +0100
@@ -31,7 +31,7 @@
         self._twreq = req
         super(CubicWebTwistedRequestAdapter, self).__init__(
             vreg, https, req.args, headers=req.received_headers)
-        for key, name_stream_list in req.files.iteritems():
+        for key, name_stream_list in req.files.items():
             for name, stream in name_stream_list:
                 if name is not None:
                     name = unicode(name, self.encoding)
--- a/etwist/server.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/etwist/server.py	Thu Dec 10 12:34:15 2015 +0100
@@ -22,8 +22,10 @@
 import select
 import traceback
 import threading
-from urlparse import urlsplit, urlunsplit
 from cgi import FieldStorage, parse_header
+
+from six.moves.urllib.parse import urlsplit, urlunsplit
+
 from cubicweb.statsd_logger import statsd_timeit
 
 from twisted.internet import reactor, task, threads
--- a/etwist/service.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/etwist/service.py	Thu Dec 10 12:34:15 2015 +0100
@@ -15,6 +15,8 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
+from __future__ import print_function
+
 import os
 import sys
 
@@ -22,7 +24,7 @@
     import win32serviceutil
     import win32service
 except ImportError:
-    print 'Win32 extensions for Python are likely not installed.'
+    print('Win32 extensions for Python are likely not installed.')
     sys.exit(3)
 
 from os.path import join
--- a/etwist/twctl.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/etwist/twctl.py	Thu Dec 10 12:34:15 2015 +0100
@@ -17,10 +17,6 @@
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """cubicweb-clt handlers for twisted"""
 
-from os.path import join
-
-from logilab.common.shellutils import rm
-
 from cubicweb.toolsutils import CommandHandler
 from cubicweb.web.webctl import WebCreateHandler, WebUpgradeHandler
 
@@ -36,9 +32,6 @@
 
     def start_server(self, config):
         from cubicweb.etwist import server
-        config.info('clear ui caches')
-        for cachedir in ('uicache', 'uicachehttps'):
-            rm(join(config.appdatahome, cachedir, '*'))
         return server.run(config)
 
 class TWStopHandler(CommandHandler):
--- a/ext/rest.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/ext/rest.py	Thu Dec 10 12:34:15 2015 +0100
@@ -38,7 +38,9 @@
 from itertools import chain
 from logging import getLogger
 from os.path import join
-from urlparse import urlsplit
+
+from six import text_type
+from six.moves.urllib.parse import urlsplit
 
 from docutils import statemachine, nodes, utils, io
 from docutils.core import Publisher
@@ -172,7 +174,7 @@
         rql = params['rql']
         if vid is None:
             vid = params.get('vid')
-    except (ValueError, KeyError), exc:
+    except (ValueError, KeyError) as exc:
         msg = inliner.reporter.error('Could not parse bookmark path %s [%s].'
                                      % (bookmark.path, exc), line=lineno)
         prb = inliner.problematic(rawtext, rawtext, msg)
@@ -186,7 +188,7 @@
             vid = 'noresult'
         view = _cw.vreg['views'].select(vid, _cw, rset=rset)
         content = view.render()
-    except Exception, exc:
+    except Exception as exc:
         content = 'An error occurred while interpreting directive bookmark: %r' % exc
     set_classes(options)
     return [nodes.raw('', content, format='html')], []
@@ -401,7 +403,7 @@
       the data formatted as HTML or the original data if an error occurred
     """
     req = context._cw
-    if isinstance(data, unicode):
+    if isinstance(data, text_type):
         encoding = 'unicode'
         # remove unprintable characters unauthorized in xml
         data = data.translate(ESC_UCAR_TABLE)
@@ -446,8 +448,8 @@
         return res
     except BaseException:
         LOGGER.exception('error while publishing ReST text')
-        if not isinstance(data, unicode):
-            data = unicode(data, encoding, 'replace')
+        if not isinstance(data, text_type):
+            data = text_type(data, encoding, 'replace')
         return xml_escape(req._('error while publishing ReST text')
                            + '\n\n' + data)
 
--- a/ext/tal.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/ext/tal.py	Thu Dec 10 12:34:15 2015 +0100
@@ -184,7 +184,10 @@
             interpreter.execute(self)
         except UnicodeError as unierror:
             LOGGER.exception(str(unierror))
-            raise simpleTALES.ContextContentException("found non-unicode %r string in Context!" % unierror.args[1]), None, sys.exc_info()[-1]
+            exc = simpleTALES.ContextContentException(
+                "found non-unicode %r string in Context!" % unierror.args[1])
+            exc.__traceback__ = sys.exc_info()[-1]
+            raise exc
 
 
 def compile_template(template):
@@ -203,7 +206,7 @@
     :type filepath: str
     :param template: path of the file to compile
     """
-    fp = file(filepath)
+    fp = open(filepath)
     file_content = unicode(fp.read()) # template file should be pure ASCII
     fp.close()
     return compile_template(file_content)
@@ -232,7 +235,8 @@
         result = eval(expr, globals, locals)
     except Exception as ex:
         ex = ex.__class__('in %r: %s' % (expr, ex))
-        raise ex, None, sys.exc_info()[-1]
+        ex.__traceback__ = sys.exc_info()[-1]
+        raise ex
     if (isinstance (result, simpleTALES.ContextVariable)):
         return result.value()
     return result
--- a/ext/test/data/views.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/ext/test/data/views.py	Thu Dec 10 12:34:15 2015 +0100
@@ -21,4 +21,3 @@
 
 class CustomRsetTableView(tableview.RsetTableView):
     __regid__ = 'mytable'
-
--- a/ext/test/unittest_rest.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/ext/test/unittest_rest.py	Thu Dec 10 12:34:15 2015 +0100
@@ -15,6 +15,8 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
+from six import PY3
+
 from logilab.common.testlib import unittest_main
 from cubicweb.devtools.testlib import CubicWebTC
 
@@ -87,7 +89,9 @@
             context = self.context(req)
             out = rest_publish(context, ':rql:`Any X WHERE X is CWUser:toto`')
             self.assertTrue(out.startswith("<p>an error occurred while interpreting this "
-                                           "rql directive: ObjectNotFound(u'toto',)</p>"))
+                                           "rql directive: ObjectNotFound(%s'toto',)</p>" %
+                                           ('' if PY3 else 'u')),
+                            out)
 
     def test_rql_role_without_vid(self):
         with self.admin_access.web_request() as req:
@@ -229,7 +233,7 @@
    %(rql)s
                 """ % {'rql': rql,
                        'colvids': ', '.join(["%d=%s" % (k, v)
-                                             for k, v in colvids.iteritems()])
+                                             for k, v in colvids.items()])
                    })
             view = self.vreg['views'].select('table', req, rset=req.execute(rql))
             view.cellvids = colvids
--- a/gettext.py	Wed Dec 09 18:42:13 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,795 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb 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 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
-"""Internationalization and localization support.
-
-This module provides internationalization (I18N) and localization (L10N)
-support for your Python programs by providing an interface to the GNU gettext
-message catalog library.
-
-I18N refers to the operation by which a program is made aware of multiple
-languages.  L10N refers to the adaptation of your program, once
-internationalized, to the local language and cultural habits.
-
-"""
-
-# This module represents the integration of work, contributions, feedback, and
-# suggestions from the following people:
-#
-# Martin von Loewis, who wrote the initial implementation of the underlying
-# C-based libintlmodule (later renamed _gettext), along with a skeletal
-# gettext.py implementation.
-#
-# Peter Funk, who wrote fintl.py, a fairly complete wrapper around intlmodule,
-# which also included a pure-Python implementation to read .mo files if
-# intlmodule wasn't available.
-#
-# James Henstridge, who also wrote a gettext.py module, which has some
-# interesting, but currently unsupported experimental features: the notion of
-# a Catalog class and instances, and the ability to add to a catalog file via
-# a Python API.
-#
-# Barry Warsaw integrated these modules, wrote the .install() API and code,
-# and conformed all C and Python code to Python's coding standards.
-#
-# Francois Pinard and Marc-Andre Lemburg also contributed valuably to this
-# module.
-#
-# J. David Ibanez implemented plural forms. Bruno Haible fixed some bugs.
-#
-# TODO:
-# - Lazy loading of .mo files.  Currently the entire catalog is loaded into
-#   memory, but that's probably bad for large translated programs.  Instead,
-#   the lexical sort of original strings in GNU .mo files should be exploited
-#   to do binary searches and lazy initializations.  Or you might want to use
-#   the undocumented double-hash algorithm for .mo files with hash tables, but
-#   you'll need to study the GNU gettext code to do this.
-#
-# - Support Solaris .mo file formats.  Unfortunately, we've been unable to
-#   find this format documented anywhere.
-
-
-import locale, copy, os, re, struct, sys
-from errno import ENOENT
-
-
-__all__ = ['NullTranslations', 'GNUTranslations', 'Catalog',
-           'find', 'translation', 'install', 'textdomain', 'bindtextdomain',
-           'dgettext', 'dngettext', 'gettext', 'ngettext',
-           ]
-
-_default_localedir = os.path.join(sys.prefix, 'share', 'locale')
-
-
-def test(condition, true, false):
-    """
-    Implements the C expression:
-
-      condition ? true : false
-
-    Required to correctly interpret plural forms.
-    """
-    if condition:
-        return true
-    else:
-        return false
-
-
-def c2py(plural):
-    """Gets a C expression as used in PO files for plural forms and returns a
-    Python lambda function that implements an equivalent expression.
-    """
-    # Security check, allow only the "n" identifier
-    try:
-        from cStringIO import StringIO
-    except ImportError:
-        from StringIO import StringIO
-    import token, tokenize
-    tokens = tokenize.generate_tokens(StringIO(plural).readline)
-    try:
-        danger = [x for x in tokens if x[0] == token.NAME and x[1] != 'n']
-    except tokenize.TokenError:
-        raise ValueError, \
-              'plural forms expression error, maybe unbalanced parenthesis'
-    else:
-        if danger:
-            raise ValueError, 'plural forms expression could be dangerous'
-
-    # Replace some C operators by their Python equivalents
-    plural = plural.replace('&&', ' and ')
-    plural = plural.replace('||', ' or ')
-
-    expr = re.compile(r'\!([^=])')
-    plural = expr.sub(' not \\1', plural)
-
-    # Regular expression and replacement function used to transform
-    # "a?b:c" to "test(a,b,c)".
-    expr = re.compile(r'(.*?)\?(.*?):(.*)')
-    def repl(x):
-        return "test(%s, %s, %s)" % (x.group(1), x.group(2),
-                                     expr.sub(repl, x.group(3)))
-
-    # Code to transform the plural expression, taking care of parentheses
-    stack = ['']
-    for c in plural:
-        if c == '(':
-            stack.append('')
-        elif c == ')':
-            if len(stack) == 1:
-                # Actually, we never reach this code, because unbalanced
-                # parentheses get caught in the security check at the
-                # beginning.
-                raise ValueError, 'unbalanced parenthesis in plural form'
-            s = expr.sub(repl, stack.pop())
-            stack[-1] += '(%s)' % s
-        else:
-            stack[-1] += c
-    plural = expr.sub(repl, stack.pop())
-
-    return eval('lambda n: int(%s)' % plural)
-
-
-
-def _expand_lang(locale):
-    from locale import normalize
-    locale = normalize(locale)
-    COMPONENT_CODESET   = 1 << 0
-    COMPONENT_TERRITORY = 1 << 1
-    COMPONENT_MODIFIER  = 1 << 2
-    # split up the locale into its base components
-    mask = 0
-    pos = locale.find('@')
-    if pos >= 0:
-        modifier = locale[pos:]
-        locale = locale[:pos]
-        mask |= COMPONENT_MODIFIER
-    else:
-        modifier = ''
-    pos = locale.find('.')
-    if pos >= 0:
-        codeset = locale[pos:]
-        locale = locale[:pos]
-        mask |= COMPONENT_CODESET
-    else:
-        codeset = ''
-    pos = locale.find('_')
-    if pos >= 0:
-        territory = locale[pos:]
-        locale = locale[:pos]
-        mask |= COMPONENT_TERRITORY
-    else:
-        territory = ''
-    language = locale
-    ret = []
-    for i in range(mask+1):
-        if not (i & ~mask):  # if all components for this combo exist ...
-            val = language
-            if i & COMPONENT_TERRITORY: val += territory
-            if i & COMPONENT_CODESET:   val += codeset
-            if i & COMPONENT_MODIFIER:  val += modifier
-            ret.append(val)
-    ret.reverse()
-    return ret
-
-
-
-class NullTranslations:
-    def __init__(self, fp=None):
-        self._info = {}
-        self._charset = None
-        self._output_charset = None
-        self._fallback = None
-        if fp is not None:
-            self._parse(fp)
-
-    def _parse(self, fp):
-        pass
-
-    def add_fallback(self, fallback):
-        if self._fallback:
-            self._fallback.add_fallback(fallback)
-        else:
-            self._fallback = fallback
-
-    def gettext(self, message):
-        if self._fallback:
-            return self._fallback.gettext(message)
-        return message
-
-    def pgettext(self, context, message):
-        if self._fallback:
-            return self._fallback.pgettext(context, message)
-        return message
-
-    def lgettext(self, message):
-        if self._fallback:
-            return self._fallback.lgettext(message)
-        return message
-
-    def lpgettext(self, context, message):
-        if self._fallback:
-            return self._fallback.lpgettext(context, message)
-        return message
-
-    def ngettext(self, msgid1, msgid2, n):
-        if self._fallback:
-            return self._fallback.ngettext(msgid1, msgid2, n)
-        if n == 1:
-            return msgid1
-        else:
-            return msgid2
-
-    def npgettext(self, context, msgid1, msgid2, n):
-        if self._fallback:
-            return self._fallback.npgettext(context, msgid1, msgid2, n)
-        if n == 1:
-            return msgid1
-        else:
-            return msgid2
-
-    def lngettext(self, msgid1, msgid2, n):
-        if self._fallback:
-            return self._fallback.lngettext(msgid1, msgid2, n)
-        if n == 1:
-            return msgid1
-        else:
-            return msgid2
-
-    def lnpgettext(self, context, msgid1, msgid2, n):
-        if self._fallback:
-            return self._fallback.lnpgettext(context, msgid1, msgid2, n)
-        if n == 1:
-            return msgid1
-        else:
-            return msgid2
-
-    def ugettext(self, message):
-        if self._fallback:
-            return self._fallback.ugettext(message)
-        return unicode(message)
-
-    def upgettext(self, context, message):
-        if self._fallback:
-            return self._fallback.upgettext(context, message)
-        return unicode(message)
-
-    def ungettext(self, msgid1, msgid2, n):
-        if self._fallback:
-            return self._fallback.ungettext(msgid1, msgid2, n)
-        if n == 1:
-            return unicode(msgid1)
-        else:
-            return unicode(msgid2)
-
-    def unpgettext(self, context, msgid1, msgid2, n):
-        if self._fallback:
-            return self._fallback.unpgettext(context, msgid1, msgid2, n)
-        if n == 1:
-            return unicode(msgid1)
-        else:
-            return unicode(msgid2)
-
-    def info(self):
-        return self._info
-
-    def charset(self):
-        return self._charset
-
-    def output_charset(self):
-        return self._output_charset
-
-    def set_output_charset(self, charset):
-        self._output_charset = charset
-
-    def install(self, unicode=False, names=None):
-        import __builtin__
-        __builtin__.__dict__['_'] = unicode and self.ugettext or self.gettext
-        if hasattr(names, "__contains__"):
-            if "gettext" in names:
-                __builtin__.__dict__['gettext'] = __builtin__.__dict__['_']
-            if "pgettext" in names:
-                __builtin__.__dict__['pgettext'] = (unicode and self.upgettext
-                                                    or self.pgettext)
-            if "ngettext" in names:
-                __builtin__.__dict__['ngettext'] = (unicode and self.ungettext
-                                                             or self.ngettext)
-            if "npgettext" in names:
-                __builtin__.__dict__['npgettext'] = \
-                    (unicode and self.unpgettext or self.npgettext)
-            if "lgettext" in names:
-                __builtin__.__dict__['lgettext'] = self.lgettext
-            if "lpgettext" in names:
-                __builtin__.__dict__['lpgettext'] = self.lpgettext
-            if "lngettext" in names:
-                __builtin__.__dict__['lngettext'] = self.lngettext
-            if "lnpgettext" in names:
-                __builtin__.__dict__['lnpgettext'] = self.lnpgettext
-
-
-class GNUTranslations(NullTranslations):
-    # Magic number of .mo files
-    LE_MAGIC = 0x950412deL
-    BE_MAGIC = 0xde120495L
-
-    # The encoding of a msgctxt and a msgid in a .mo file is
-    # msgctxt + "\x04" + msgid (gettext version >= 0.15)
-    CONTEXT_ENCODING = "%s\x04%s"
-
-    def _parse(self, fp):
-        """Override this method to support alternative .mo formats."""
-        unpack = struct.unpack
-        filename = getattr(fp, 'name', '')
-        # Parse the .mo file header, which consists of 5 little endian 32
-        # bit words.
-        self._catalog = catalog = {}
-        self.plural = lambda n: int(n != 1) # germanic plural by default
-        buf = fp.read()
-        buflen = len(buf)
-        # Are we big endian or little endian?
-        magic = unpack('<I', buf[:4])[0]
-        if magic == self.LE_MAGIC:
-            version, msgcount, masteridx, transidx = unpack('<4I', buf[4:20])
-            ii = '<II'
-        elif magic == self.BE_MAGIC:
-            version, msgcount, masteridx, transidx = unpack('>4I', buf[4:20])
-            ii = '>II'
-        else:
-            raise IOError(0, 'Bad magic number', filename)
-        # Now put all messages from the .mo file buffer into the catalog
-        # dictionary.
-        for i in xrange(0, msgcount):
-            mlen, moff = unpack(ii, buf[masteridx:masteridx+8])
-            mend = moff + mlen
-            tlen, toff = unpack(ii, buf[transidx:transidx+8])
-            tend = toff + tlen
-            if mend < buflen and tend < buflen:
-                msg = buf[moff:mend]
-                tmsg = buf[toff:tend]
-            else:
-                raise IOError(0, 'File is corrupt', filename)
-            # See if we're looking at GNU .mo conventions for metadata
-            if mlen == 0:
-                # Catalog description
-                lastk = k = None
-                for item in tmsg.splitlines():
-                    item = item.strip()
-                    if not item:
-                        continue
-                    if ':' in item:
-                        k, v = item.split(':', 1)
-                        k = k.strip().lower()
-                        v = v.strip()
-                        self._info[k] = v
-                        lastk = k
-                    elif lastk:
-                        self._info[lastk] += '\n' + item
-                    if k == 'content-type':
-                        self._charset = v.split('charset=')[1]
-                    elif k == 'plural-forms':
-                        v = v.split(';')
-                        plural = v[1].split('plural=')[1]
-                        self.plural = c2py(plural)
-            # Note: we unconditionally convert both msgids and msgstrs to
-            # Unicode using the character encoding specified in the charset
-            # parameter of the Content-Type header.  The gettext documentation
-            # strongly encourages msgids to be us-ascii, but some appliations
-            # require alternative encodings (e.g. Zope's ZCML and ZPT).  For
-            # traditional gettext applications, the msgid conversion will
-            # cause no problems since us-ascii should always be a subset of
-            # the charset encoding.  We may want to fall back to 8-bit msgids
-            # if the Unicode conversion fails.
-            if '\x00' in msg:
-                # Plural forms
-                msgid1, msgid2 = msg.split('\x00')
-                tmsg = tmsg.split('\x00')
-                if self._charset:
-                    msgid1 = unicode(msgid1, self._charset)
-                    tmsg = [unicode(x, self._charset) for x in tmsg]
-                for i in range(len(tmsg)):
-                    catalog[(msgid1, i)] = tmsg[i]
-            else:
-                if self._charset:
-                    msg = unicode(msg, self._charset)
-                    tmsg = unicode(tmsg, self._charset)
-                catalog[msg] = tmsg
-            # advance to next entry in the seek tables
-            masteridx += 8
-            transidx += 8
-
-    def gettext(self, message):
-        missing = object()
-        tmsg = self._catalog.get(message, missing)
-        if tmsg is missing:
-            if self._fallback:
-                return self._fallback.gettext(message)
-            return message
-        # Encode the Unicode tmsg back to an 8-bit string, if possible
-        if self._output_charset:
-            return tmsg.encode(self._output_charset)
-        elif self._charset:
-            return tmsg.encode(self._charset)
-        return tmsg
-
-    def pgettext(self, context, message):
-        ctxt_msg_id = self.CONTEXT_ENCODING % (context, message)
-        missing = object()
-        tmsg = self._catalog.get(ctxt_msg_id, missing)
-        if tmsg is missing:
-            if self._fallback:
-                return self._fallback.pgettext(context, message)
-            return message
-        # Encode the Unicode tmsg back to an 8-bit string, if possible
-        if self._output_charset:
-            return tmsg.encode(self._output_charset)
-        elif self._charset:
-            return tmsg.encode(self._charset)
-        return tmsg
-
-    def lgettext(self, message):
-        missing = object()
-        tmsg = self._catalog.get(message, missing)
-        if tmsg is missing:
-            if self._fallback:
-                return self._fallback.lgettext(message)
-            return message
-        if self._output_charset:
-            return tmsg.encode(self._output_charset)
-        return tmsg.encode(locale.getpreferredencoding())
-
-    def lpgettext(self, context, message):
-        ctxt_msg_id = self.CONTEXT_ENCODING % (context, message)
-        missing = object()
-        tmsg = self._catalog.get(ctxt_msg_id, missing)
-        if tmsg is missing:
-            if self._fallback:
-                return self._fallback.lpgettext(context, message)
-            return message
-        if self._output_charset:
-            return tmsg.encode(self._output_charset)
-        return tmsg.encode(locale.getpreferredencoding())
-
-    def ngettext(self, msgid1, msgid2, n):
-        try:
-            tmsg = self._catalog[(msgid1, self.plural(n))]
-            if self._output_charset:
-                return tmsg.encode(self._output_charset)
-            elif self._charset:
-                return tmsg.encode(self._charset)
-            return tmsg
-        except KeyError:
-            if self._fallback:
-                return self._fallback.ngettext(msgid1, msgid2, n)
-            if n == 1:
-                return msgid1
-            else:
-                return msgid2
-
-    def npgettext(self, context, msgid1, msgid2, n):
-        ctxt_msg_id = self.CONTEXT_ENCODING % (context, msgid1)
-        try:
-            tmsg = self._catalog[(ctxt_msg_id, self.plural(n))]
-            if self._output_charset:
-                return tmsg.encode(self._output_charset)
-            elif self._charset:
-                return tmsg.encode(self._charset)
-            return tmsg
-        except KeyError:
-            if self._fallback:
-                return self._fallback.npgettext(context, msgid1, msgid2, n)
-            if n == 1:
-                return msgid1
-            else:
-                return msgid2        
-
-    def lngettext(self, msgid1, msgid2, n):
-        try:
-            tmsg = self._catalog[(msgid1, self.plural(n))]
-            if self._output_charset:
-                return tmsg.encode(self._output_charset)
-            return tmsg.encode(locale.getpreferredencoding())
-        except KeyError:
-            if self._fallback:
-                return self._fallback.lngettext(msgid1, msgid2, n)
-            if n == 1:
-                return msgid1
-            else:
-                return msgid2
-
-    def lnpgettext(self, context, msgid1, msgid2, n):
-        ctxt_msg_id = self.CONTEXT_ENCODING % (context, msgid1)
-        try:
-            tmsg = self._catalog[(ctxt_msg_id, self.plural(n))]
-            if self._output_charset:
-                return tmsg.encode(self._output_charset)
-            return tmsg.encode(locale.getpreferredencoding())
-        except KeyError:
-            if self._fallback:
-                return self._fallback.lnpgettext(context, msgid1, msgid2, n)
-            if n == 1:
-                return msgid1
-            else:
-                return msgid2
-
-    def ugettext(self, message):
-        missing = object()
-        tmsg = self._catalog.get(message, missing)
-        if tmsg is missing:
-            if self._fallback:
-                return self._fallback.ugettext(message)
-            return unicode(message)
-        return tmsg
-
-    def upgettext(self, context, message):
-        ctxt_message_id = self.CONTEXT_ENCODING % (context, message)
-        missing = object()
-        tmsg = self._catalog.get(ctxt_message_id, missing)
-        if tmsg is missing:
-            # XXX logilab patch for compat w/ catalog generated by cw < 3.5
-            return self.ugettext(message)
-            if self._fallback:
-                return self._fallback.upgettext(context, message)
-            return unicode(message)
-        return tmsg
-
-    def ungettext(self, msgid1, msgid2, n):
-        try:
-            tmsg = self._catalog[(msgid1, self.plural(n))]
-        except KeyError:
-            if self._fallback:
-                return self._fallback.ungettext(msgid1, msgid2, n)
-            if n == 1:
-                tmsg = unicode(msgid1)
-            else:
-                tmsg = unicode(msgid2)
-        return tmsg
-
-    def unpgettext(self, context, msgid1, msgid2, n):
-        ctxt_message_id = self.CONTEXT_ENCODING % (context, msgid1)
-        try:
-            tmsg = self._catalog[(ctxt_message_id, self.plural(n))]
-        except KeyError:
-            if self._fallback:
-                return self._fallback.unpgettext(context, msgid1, msgid2, n)
-            if n == 1:
-                tmsg = unicode(msgid1)
-            else:
-                tmsg = unicode(msgid2)
-        return tmsg
-
-
-# Locate a .mo file using the gettext strategy
-def find(domain, localedir=None, languages=None, all=0):
-    # Get some reasonable defaults for arguments that were not supplied
-    if localedir is None:
-        localedir = _default_localedir
-    if languages is None:
-        languages = []
-        for envar in ('LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'):
-            val = os.environ.get(envar)
-            if val:
-                languages = val.split(':')
-                break
-        if 'C' not in languages:
-            languages.append('C')
-    # now normalize and expand the languages
-    nelangs = []
-    for lang in languages:
-        for nelang in _expand_lang(lang):
-            if nelang not in nelangs:
-                nelangs.append(nelang)
-    # select a language
-    if all:
-        result = []
-    else:
-        result = None
-    for lang in nelangs:
-        if lang == 'C':
-            break
-        mofile = os.path.join(localedir, lang, 'LC_MESSAGES', '%s.mo' % domain)
-        if os.path.exists(mofile):
-            if all:
-                result.append(mofile)
-            else:
-                return mofile
-    return result
-
-
-
-# a mapping between absolute .mo file path and Translation object
-_translations = {}
-
-def translation(domain, localedir=None, languages=None,
-                class_=None, fallback=False, codeset=None):
-    if class_ is None:
-        class_ = GNUTranslations
-    mofiles = find(domain, localedir, languages, all=1)
-    if not mofiles:
-        if fallback:
-            return NullTranslations()
-        raise IOError(ENOENT, 'No translation file found for domain', domain)
-    # TBD: do we need to worry about the file pointer getting collected?
-    # Avoid opening, reading, and parsing the .mo file after it's been done
-    # once.
-    result = None
-    for mofile in mofiles:
-        key = os.path.abspath(mofile)
-        t = _translations.get(key)
-        if t is None:
-            t = _translations.setdefault(key, class_(open(mofile, 'rb')))
-        # Copy the translation object to allow setting fallbacks and
-        # output charset. All other instance data is shared with the
-        # cached object.
-        t = copy.copy(t)
-        if codeset:
-            t.set_output_charset(codeset)
-        if result is None:
-            result = t
-        else:
-            result.add_fallback(t)
-    return result
-
-
-def install(domain, localedir=None, unicode=False, codeset=None, names=None):
-    t = translation(domain, localedir, fallback=True, codeset=codeset)
-    t.install(unicode, names)
-
-
-
-# a mapping b/w domains and locale directories
-_localedirs = {}
-# a mapping b/w domains and codesets
-_localecodesets = {}
-# current global domain, `messages' used for compatibility w/ GNU gettext
-_current_domain = 'messages'
-
-
-def textdomain(domain=None):
-    global _current_domain
-    if domain is not None:
-        _current_domain = domain
-    return _current_domain
-
-
-def bindtextdomain(domain, localedir=None):
-    global _localedirs
-    if localedir is not None:
-        _localedirs[domain] = localedir
-    return _localedirs.get(domain, _default_localedir)
-
-
-def bind_textdomain_codeset(domain, codeset=None):
-    global _localecodesets
-    if codeset is not None:
-        _localecodesets[domain] = codeset
-    return _localecodesets.get(domain)
-
-
-def dgettext(domain, message):
-    try:
-        t = translation(domain, _localedirs.get(domain, None),
-                        codeset=_localecodesets.get(domain))
-    except IOError:
-        return message
-    return t.gettext(message)
-
-def dpgettext(domain, context, message):
-    try:
-        t = translation(domain, _localedirs.get(domain, None),
-                        codeset=_localecodesets.get(domain))
-    except IOError:
-        return message
-    return t.pgettext(context, message)
-
-def ldgettext(domain, message):
-    try:
-        t = translation(domain, _localedirs.get(domain, None),
-                        codeset=_localecodesets.get(domain))
-    except IOError:
-        return message
-    return t.lgettext(message)
-
-def ldpgettext(domain, context, message):
-    try:
-        t = translation(domain, _localedirs.get(domain, None),
-                        codeset=_localecodesets.get(domain))
-    except IOError:
-        return message
-    return t.lpgettext(context, message)
-
-def dngettext(domain, msgid1, msgid2, n):
-    try:
-        t = translation(domain, _localedirs.get(domain, None),
-                        codeset=_localecodesets.get(domain))
-    except IOError:
-        if n == 1:
-            return msgid1
-        else:
-            return msgid2
-    return t.ngettext(msgid1, msgid2, n)
-
-def dnpgettext(domain, context, msgid1, msgid2, n):
-    try:
-        t = translation(domain, _localedirs.get(domain, None),
-                        codeset=_localecodesets.get(domain))
-    except IOError:
-        if n == 1:
-            return msgid1
-        else:
-            return msgid2
-    return t.npgettext(context, msgid1, msgid2, n)
-
-def ldngettext(domain, msgid1, msgid2, n):
-    try:
-        t = translation(domain, _localedirs.get(domain, None),
-                        codeset=_localecodesets.get(domain))
-    except IOError:
-        if n == 1:
-            return msgid1
-        else:
-            return msgid2
-    return t.lngettext(msgid1, msgid2, n)
-
-def ldnpgettext(domain, context, msgid1, msgid2, n):
-    try:
-        t = translation(domain, _localedirs.get(domain, None),
-                        codeset=_localecodesets.get(domain))
-    except IOError:
-        if n == 1:
-            return msgid1
-        else:
-            return msgid2
-    return t.lnpgettext(context, msgid1, msgid2, n)
-
-def gettext(message):
-    return dgettext(_current_domain, message)
-
-def pgettext(context, message):
-    return dpgettext(_current_domain, context, message)
-
-def lgettext(message):
-    return ldgettext(_current_domain, message)
-
-def lpgettext(context, message):
-    return ldpgettext(_current_domain, context, message)
-
-def ngettext(msgid1, msgid2, n):
-    return dngettext(_current_domain, msgid1, msgid2, n)
-
-def npgettext(context, msgid1, msgid2, n):
-    return dnpgettext(_current_domain, context, msgid1, msgid2, n)
-
-def lngettext(msgid1, msgid2, n):
-    return ldngettext(_current_domain, msgid1, msgid2, n)
-
-def lnpgettext(context, msgid1, msgid2, n):
-    return ldnpgettext(_current_domain, context, msgid1, msgid2, n)
-
-# dcgettext() has been deemed unnecessary and is not implemented.
-
-# James Henstridge's Catalog constructor from GNOME gettext.  Documented usage
-# was:
-#
-#    import gettext
-#    cat = gettext.Catalog(PACKAGE, localedir=LOCALEDIR)
-#    _ = cat.gettext
-#    print _('Hello World')
-
-# The resulting catalog object currently don't support access through a
-# dictionary API, which was supported (but apparently unused) in GNOME
-# gettext.
-
-Catalog = translation
--- a/hooks/__init__.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/hooks/__init__.py	Thu Dec 10 12:34:15 2015 +0100
@@ -52,7 +52,7 @@
         def update_feeds(repo):
             # take a list to avoid iterating on a dictionary whose size may
             # change
-            for uri, source in list(repo.sources_by_uri.iteritems()):
+            for uri, source in list(repo.sources_by_uri.items()):
                 if (uri == 'system'
                     or not repo.config.source_enabled(source)
                     or not source.config['synchronize']):
@@ -72,7 +72,7 @@
 
     def __call__(self):
         def expire_dataimports(repo=self.repo):
-            for uri, source in repo.sources_by_uri.iteritems():
+            for uri, source in repo.sources_by_uri.items():
                 if (uri == 'system'
                     or not repo.config.source_enabled(source)):
                     continue
--- a/hooks/integrity.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/hooks/integrity.py	Thu Dec 10 12:34:15 2015 +0100
@@ -20,10 +20,12 @@
 """
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from threading import Lock
 
+from six import text_type
+
 from cubicweb import validation_error, neg_role
 from cubicweb.schema import (META_RTYPES, WORKFLOW_RTYPES,
                              RQLConstraint, RQLUniqueConstraint)
@@ -45,7 +47,7 @@
 
     This lock used to avoid potential integrity pb when checking
     RQLUniqueConstraint in two different transactions, as explained in
-    http://intranet.logilab.fr/jpl/ticket/36564
+    https://extranet.logilab.fr/3577926
     """
     if 'uniquecstrholder' in cnx.transaction_data:
         return
@@ -109,9 +111,10 @@
     category = 'integrity'
 
 
-class EnsureSymmetricRelationsAdd(hook.Hook):
+class _EnsureSymmetricRelationsAdd(hook.Hook):
     """ ensure X r Y => Y r X iff r is symmetric """
     __regid__ = 'cw.add_ensure_symmetry'
+    __abstract__ = True
     category = 'activeintegrity'
     events = ('after_add_relation',)
     # __select__ is set in the registration callback
@@ -121,9 +124,10 @@
                                                  self.rtype, self.eidfrom)
 
 
-class EnsureSymmetricRelationsDelete(hook.Hook):
+class _EnsureSymmetricRelationsDelete(hook.Hook):
     """ ensure X r Y => Y r X iff r is symmetric """
     __regid__ = 'cw.delete_ensure_symmetry'
+    __abstract__ = True
     category = 'activeintegrity'
     events = ('after_delete_relation',)
     # __select__ is set in the registration callback
@@ -247,7 +251,7 @@
     def __call__(self):
         entity = self.entity
         eschema = entity.e_schema
-        for attr, val in entity.cw_edited.iteritems():
+        for attr, val in entity.cw_edited.items():
             if eschema.subjrels[attr].final and eschema.has_unique_values(attr):
                 if val is None:
                     continue
@@ -286,13 +290,13 @@
         entity = self.entity
         metaattrs = entity.e_schema.meta_attributes()
         edited = entity.cw_edited
-        for metaattr, (metadata, attr) in metaattrs.iteritems():
+        for metaattr, (metadata, attr) in metaattrs.items():
             if metadata == 'format' and attr in edited:
                 try:
                     value = edited[attr]
                 except KeyError:
                     continue # no text to tidy
-                if isinstance(value, unicode): # filter out None and Binary
+                if isinstance(value, text_type): # filter out None and Binary
                     if getattr(entity, str(metaattr)) == 'text/html':
                         edited[attr] = soup2xhtml(value, self._cw.encoding)
 
@@ -335,6 +339,9 @@
     vreg.register_all(globals().values(), __name__)
     symmetric_rtypes = [rschema.type for rschema in vreg.schema.relations()
                         if rschema.symmetric]
-    EnsureSymmetricRelationsAdd.__select__ = hook.Hook.__select__ & hook.match_rtype(*symmetric_rtypes)
-    EnsureSymmetricRelationsDelete.__select__ = hook.Hook.__select__ & hook.match_rtype(*symmetric_rtypes)
-
+    class EnsureSymmetricRelationsAdd(_EnsureSymmetricRelationsAdd):
+        __select__ = _EnsureSymmetricRelationsAdd.__select__ & hook.match_rtype(*symmetric_rtypes)
+    vreg.register(EnsureSymmetricRelationsAdd)
+    class EnsureSymmetricRelationsDelete(_EnsureSymmetricRelationsDelete):
+        __select__ = _EnsureSymmetricRelationsDelete.__select__ & hook.match_rtype(*symmetric_rtypes)
+    vreg.register(EnsureSymmetricRelationsDelete)
--- a/hooks/security.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/hooks/security.py	Thu Dec 10 12:34:15 2015 +0100
@@ -207,4 +207,3 @@
         rdef = rschema.rdef(self._cw.entity_metas(self.eidfrom)['type'],
                             self._cw.entity_metas(self.eidto)['type'])
         rdef.check_perm(self._cw, 'delete', fromeid=self.eidfrom, toeid=self.eidto)
-
--- a/hooks/synccomputed.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/hooks/synccomputed.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,7 +18,7 @@
 """Hooks for synchronizing computed attributes"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from collections import defaultdict
 
@@ -40,7 +40,7 @@
             self._container[computed_attribute] = set((eid,))
 
     def precommit_event(self):
-        for computed_attribute_rdef, eids in self.get_data().iteritems():
+        for computed_attribute_rdef, eids in self.get_data().items():
             attr = computed_attribute_rdef.rtype
             formula  = computed_attribute_rdef.formula
             select = self.cnx.repo.vreg.rqlhelper.parse(formula).children[0]
@@ -110,7 +110,7 @@
 
     def __call__(self):
         edited_attributes = frozenset(self.entity.cw_edited)
-        for rdef, used_attributes in self.attributes_computed_attributes.iteritems():
+        for rdef, used_attributes in self.attributes_computed_attributes.items():
             if edited_attributes.intersection(used_attributes):
                 # XXX optimize if the modified attributes belong to the same
                 # entity as the computed attribute
@@ -178,7 +178,7 @@
                             self.computed_attribute_by_relation[depend_on_rdef].append(rdef)
 
     def generate_entity_creation_hooks(self):
-        for etype, computed_attributes in self.computed_attribute_by_etype.iteritems():
+        for etype, computed_attributes in self.computed_attribute_by_etype.items():
             regid = 'computed_attribute.%s_created' % etype
             selector = hook.is_instance(etype)
             yield type('%sCreatedHook' % etype,
@@ -188,7 +188,7 @@
                         'computed_attributes': computed_attributes})
 
     def generate_relation_change_hooks(self):
-        for rdef, computed_attributes in self.computed_attribute_by_relation.iteritems():
+        for rdef, computed_attributes in self.computed_attribute_by_relation.items():
             regid = 'computed_attribute.%s_modified' % rdef.rtype
             selector = hook.match_rtype(rdef.rtype.type,
                                         frometypes=(rdef.subject.type,),
@@ -206,7 +206,7 @@
                         'optimized_computed_attributes': optimized_computed_attributes})
 
     def generate_entity_update_hooks(self):
-        for etype, attributes_computed_attributes in self.computed_attribute_by_etype_attrs.iteritems():
+        for etype, attributes_computed_attributes in self.computed_attribute_by_etype_attrs.items():
             regid = 'computed_attribute.%s_updated' % etype
             selector = hook.is_instance(etype)
             yield type('%sModifiedHook' % etype,
--- a/hooks/syncschema.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/hooks/syncschema.py	Thu Dec 10 12:34:15 2015 +0100
@@ -1,4 +1,4 @@
-# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2015 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
 # This file is part of CubicWeb.
@@ -24,7 +24,7 @@
 """
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from copy import copy
 from hashlib import md5
@@ -37,7 +37,7 @@
 from cubicweb import validation_error
 from cubicweb.predicates import is_instance
 from cubicweb.schema import (SCHEMA_TYPES, META_RTYPES, VIRTUAL_RTYPES,
-                             CONSTRAINTS, ETYPE_NAME_MAP, display_name)
+                             CONSTRAINTS, UNIQUE_CONSTRAINTS, ETYPE_NAME_MAP)
 from cubicweb.server import hook, schemaserial as ss, schema2sql as y2sql
 from cubicweb.server.sqlutils import SQL_PREFIX
 from cubicweb.hooks.synccomputed import RecomputeAttributeOperation
@@ -158,24 +158,26 @@
         cnx.transaction_data.setdefault('pendingrtypes', set()).add(rtype)
 
 
-class DropColumn(hook.Operation):
+class DropColumn(hook.DataOperationMixIn, hook.Operation):
     """actually remove the attribut's column from entity table in the system
     database
     """
-    table = column = None # make pylint happy
     def precommit_event(self):
-        cnx, table, column = self.cnx, self.table, self.column
-        source = cnx.repo.system_source
-        # drop index if any
-        source.drop_index(cnx, table, column)
-        if source.dbhelper.alter_column_support:
-            cnx.system_sql('ALTER TABLE %s DROP COLUMN %s' % (table, column),
-                           rollback_on_failure=False)
-            self.info('dropped column %s from table %s', column, table)
-        else:
-            # not supported by sqlite for instance
-            self.error('dropping column not supported by the backend, handle '
-                       'it yourself (%s.%s)', table, column)
+        cnx = self.cnx
+        for etype, attr in self.get_data():
+            table = SQL_PREFIX + etype
+            column = SQL_PREFIX + attr
+            source = cnx.repo.system_source
+            # drop index if any
+            source.drop_index(cnx, table, column)
+            if source.dbhelper.alter_column_support:
+                cnx.system_sql('ALTER TABLE %s DROP COLUMN %s' % (table, column),
+                               rollback_on_failure=False)
+                self.info('dropped column %s from table %s', column, table)
+            else:
+                # not supported by sqlite for instance
+                self.error('dropping column not supported by the backend, handle '
+                           'it yourself (%s.%s)', table, column)
 
     # XXX revertprecommit_event
 
@@ -208,7 +210,7 @@
             repo.set_schema(repo.schema)
             # CWUser class might have changed, update current session users
             cwuser_cls = self.cnx.vreg['etypes'].etype_class('CWUser')
-            for session in repo._sessions.itervalues():
+            for session in repo._sessions.values():
                 session.user.__class__ = cwuser_cls
         except Exception:
             self.critical('error while setting schema', exc_info=True)
@@ -330,7 +332,7 @@
         self.oldvalues = dict( (attr, getattr(rschema, attr)) for attr in self.values)
         self.rschema.__dict__.update(self.values)
         # then make necessary changes to the system source database
-        if not 'inlined' in self.values:
+        if 'inlined' not in self.values:
             return # nothing to do
         inlined = self.values['inlined']
         # check in-lining is possible when inlined
@@ -360,8 +362,7 @@
             # drop existant columns
             #if cnx.repo.system_source.dbhelper.alter_column_support:
             for etype in rschema.subjects():
-                DropColumn(cnx, table=SQL_PREFIX + str(etype),
-                           column=SQL_PREFIX + rtype)
+                DropColumn.get_instance(cnx).add_data((str(etype), rtype))
         else:
             for etype in rschema.subjects():
                 try:
@@ -606,10 +607,24 @@
             if rset[0][0] == 0 and not cnx.deleted_in_transaction(rdef.subject.eid):
                 ptypes = cnx.transaction_data.setdefault('pendingrtypes', set())
                 ptypes.add(rschema.type)
-                DropColumn(cnx, table=SQL_PREFIX + str(rdef.subject),
-                           column=SQL_PREFIX + str(rschema))
+                DropColumn.get_instance(cnx).add_data((str(rdef.subject), str(rschema)))
+            elif rschema.inlined:
+                cnx.system_sql('UPDATE %s%s SET %s%s=NULL WHERE '
+                               'EXISTS(SELECT 1 FROM entities '
+                               '       WHERE eid=%s%s AND type=%%(to_etype)s)'
+                               % (SQL_PREFIX, rdef.subject, SQL_PREFIX, rdef.rtype,
+                                  SQL_PREFIX, rdef.rtype),
+                               {'to_etype': rdef.object.type})
         elif lastrel:
             DropRelationTable(cnx, str(rschema))
+        else:
+            cnx.system_sql('DELETE FROM %s_relation WHERE '
+                           'EXISTS(SELECT 1 FROM entities '
+                           '       WHERE eid=eid_from AND type=%%(from_etype)s)'
+                           ' AND EXISTS(SELECT 1 FROM entities '
+                           '       WHERE eid=eid_to AND type=%%(to_etype)s)'
+                           % rschema,
+                           {'from_etype': rdef.subject.type, 'to_etype': rdef.object.type})
         # then update the in-memory schema
         if rdef.subject not in ETYPE_NAME_MAP and rdef.object not in ETYPE_NAME_MAP:
             rschema.del_relation_def(rdef.subject, rdef.object)
@@ -647,8 +662,7 @@
         if 'indexed' in self.values:
             syssource.update_rdef_indexed(cnx, rdef)
             self.indexed_changed = True
-        if 'cardinality' in self.values and (rdef.rtype.final or
-                                             rdef.rtype.inlined) \
+        if 'cardinality' in self.values and rdef.rtype.final \
               and self.values['cardinality'][0] != self.oldvalues['cardinality'][0]:
             syssource.update_rdef_null_allowed(self.cnx, rdef)
             self.null_allowed_changed = True
@@ -717,8 +731,8 @@
             syssource.update_rdef_unique(cnx, rdef)
             self.unique_changed = True
         if cstrtype in ('BoundaryConstraint', 'IntervalBoundConstraint', 'StaticVocabularyConstraint'):
-            cstrname = 'cstr' + md5(rdef.subject.type + rdef.rtype.type + cstrtype +
-                                    (self.oldcstr.serialize() or '')).hexdigest()
+            cstrname = 'cstr' + md5((rdef.subject.type + rdef.rtype.type + cstrtype +
+                                     (self.oldcstr.serialize() or '')).encode('utf-8')).hexdigest()
             cnx.system_sql('ALTER TABLE %s%s DROP CONSTRAINT %s' % (SQL_PREFIX, rdef.subject.type, cstrname))
 
     def revertprecommit_event(self):
@@ -749,7 +763,10 @@
             return
         rdef = self.rdef = cnx.vreg.schema.schema_by_eid(rdefentity.eid)
         cstrtype = self.entity.type
-        oldcstr = self.oldcstr = rdef.constraint_by_type(cstrtype)
+        if cstrtype in UNIQUE_CONSTRAINTS:
+            oldcstr = self.oldcstr = rdef.constraint_by_type(cstrtype)
+        else:
+            oldcstr = None
         newcstr = self.newcstr = CONSTRAINTS[cstrtype].deserialize(self.entity.value)
         # in-place modification of in-memory schema first
         _set_modifiable_constraints(rdef)
@@ -769,8 +786,8 @@
             self.unique_changed = True
         if cstrtype in ('BoundaryConstraint', 'IntervalBoundConstraint', 'StaticVocabularyConstraint'):
             if oldcstr is not None:
-                oldcstrname = 'cstr' + md5(rdef.subject.type + rdef.rtype.type + cstrtype +
-                                           (self.oldcstr.serialize() or '')).hexdigest()
+                oldcstrname = 'cstr' + md5((rdef.subject.type + rdef.rtype.type + cstrtype +
+                                            (self.oldcstr.serialize() or '')).encode('ascii')).hexdigest()
                 cnx.system_sql('ALTER TABLE %s%s DROP CONSTRAINT %s' %
                                (SQL_PREFIX, rdef.subject.type, oldcstrname))
             cstrname, check = y2sql.check_constraint(rdef.subject, rdef.object, rdef.rtype.type,
@@ -905,11 +922,6 @@
             # duh, schema not found, log error and skip operation
             self.warning('no schema for %s', self.eid)
             return
-        if isinstance(erschema, RelationSchema): # XXX 3.6 migration
-            return
-        if isinstance(erschema, RelationDefinitionSchema) and \
-               self.action in ('delete', 'add'): # XXX 3.6.1 migration
-            return
         perms = list(erschema.action_permissions(self.action))
         if self.group_eid is not None:
             perm = self.cnx.entity_from_eid(self.group_eid).name
@@ -972,7 +984,6 @@
             raise validation_error(self.entity, {None: _("can't be deleted")})
         # delete every entities of this type
         if name not in ETYPE_NAME_MAP:
-            self._cw.execute('DELETE %s X' % name)
             MemSchemaCWETypeDel(self._cw, etype=name)
         DropTable(self._cw, table=SQL_PREFIX + name)
 
@@ -1155,10 +1166,6 @@
         else:
             rdeftype = 'CWRelation'
             pendingrdefs.add((subjschema, rschema, objschema))
-            if not (cnx.deleted_in_transaction(subjschema.eid) or
-                    cnx.deleted_in_transaction(objschema.eid)):
-                cnx.execute('DELETE X %s Y WHERE X is %s, Y is %s'
-                                % (rschema, subjschema, objschema))
         RDefDelOp(cnx, rdef=rdef)
 
 
--- a/hooks/syncsession.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/hooks/syncsession.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,7 +18,7 @@
 """Core hooks: synchronize living session on persistent data changes"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from cubicweb import UnknownProperty, BadConnectionId, validation_error
 from cubicweb.predicates import is_instance
@@ -26,7 +26,7 @@
 
 
 def get_user_sessions(repo, ueid):
-    for session in repo._sessions.itervalues():
+    for session in repo._sessions.values():
         if ueid == session.user.eid:
             yield session
 
@@ -114,7 +114,7 @@
     def __call__(self):
         """modify user permission, need to update users"""
         for session in get_user_sessions(self._cw.repo, self.entity.eid):
-            _DelUserOp(self._cw, session.id)
+            _DelUserOp(self._cw, session.sessionid)
 
 
 # CWProperty hooks #############################################################
--- a/hooks/syncsources.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/hooks/syncsources.py	Thu Dec 10 12:34:15 2015 +0100
@@ -17,7 +17,7 @@
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """hooks for repository sources synchronization"""
 
-_ = unicode
+from cubicweb import _
 
 from socket import gethostname
 
@@ -119,7 +119,7 @@
                 msg = _("You cannot rename the system source")
                 raise validation_error(self.entity, {('name', 'subject'): msg})
             SourceRenamedOp(self._cw, oldname=oldname, newname=newname)
-        if 'config' in self.entity.cw_edited:
+        if 'config' in self.entity.cw_edited or 'url' in self.entity.cw_edited:
             if self.entity.name == 'system' and self.entity.config:
                 msg = _("Configuration of the system source goes to "
                         "the 'sources' file, not in the database")
--- a/hooks/test/data/schema.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/hooks/test/data/schema.py	Thu Dec 10 12:34:15 2015 +0100
@@ -22,7 +22,7 @@
 
 from cubicweb.schema import ERQLExpression
 
-_ = unicode
+from cubicweb import _
 
 class friend(RelationDefinition):
     subject = ('CWUser', 'CWGroup')
--- a/hooks/test/unittest_hooks.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/hooks/test/unittest_hooks.py	Thu Dec 10 12:34:15 2015 +0100
@@ -24,9 +24,12 @@
 
 from datetime import datetime
 
+from six import text_type
+
 from cubicweb import ValidationError, AuthenticationError, BadConnectionId
 from cubicweb.devtools.testlib import CubicWebTC
 
+
 class CoreHooksTC(CubicWebTC):
 
     def test_inlined(self):
@@ -207,7 +210,7 @@
             with self.assertRaises(ValidationError) as cm:
                 cnx.execute('INSERT CWUser X: X login "admin"')
             ex = cm.exception
-            ex.translate(unicode)
+            ex.translate(text_type)
             self.assertIsInstance(ex.entity, int)
             self.assertEqual(ex.errors, {'login-subject': 'the value "admin" is already used, use another one'})
 
--- a/hooks/test/unittest_synccomputed.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/hooks/test/unittest_synccomputed.py	Thu Dec 10 12:34:15 2015 +0100
@@ -62,7 +62,7 @@
     def test_computed_attribute_by_relation(self):
         comp_by_rdef = self.dependencies.computed_attribute_by_relation
         self.assertEqual(len(comp_by_rdef), 1)
-        key, values = iter(comp_by_rdef.iteritems()).next()
+        key, values = next(iter(comp_by_rdef.items()))
         self.assertEqual(key.rtype, 'works_for')
         self.assertEqual(len(values), 1)
         self.assertEqual(values[0].rtype, 'total_salary')
@@ -73,7 +73,7 @@
         values = comp_by_attr['Person']
         self.assertEqual(len(values), 2)
         values = set((rdef.formula, tuple(v))
-                     for rdef, v in values.iteritems())
+                     for rdef, v in values.items())
         self.assertEquals(values,
                           set((('Any 2014 - D WHERE X birth_year D', tuple(('birth_year',))),
                                ('Any SUM(SA) GROUPBY X WHERE P works_for X, P salary SA', tuple(('salary',)))))
--- a/hooks/test/unittest_syncschema.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/hooks/test/unittest_syncschema.py	Thu Dec 10 12:34:15 2015 +0100
@@ -19,6 +19,7 @@
 
 from logilab.common.testlib import unittest_main
 
+from yams.constraints import BoundaryConstraint
 from cubicweb import ValidationError, Binary
 from cubicweb.schema import META_RTYPES
 from cubicweb.devtools import startpgcluster, stoppgcluster, PostgresApptestConfiguration
@@ -382,5 +383,23 @@
             self.assertEqual(cstr.values, (u'normal', u'auto', u'new'))
             cnx.execute('INSERT Transition T: T name "hop", T type "new"')
 
+    def test_add_constraint(self):
+        with self.admin_access.repo_cnx() as cnx:
+            rdef = self.schema['EmailPart'].rdef('ordernum')
+            cstr = BoundaryConstraint('>=', 0)
+            cnx.execute('INSERT CWConstraint X: X value %(v)s, X cstrtype CT, '
+                        'EDEF constrained_by X WHERE CT name %(ct)s, EDEF eid %(x)s',
+                        {'ct': cstr.__class__.__name__, 'v': cstr.serialize(), 'x': rdef.eid})
+            cnx.commit()
+            cstr2 = rdef.constraint_by_type('BoundaryConstraint')
+            self.assertEqual(cstr, cstr2)
+            cstr3 = BoundaryConstraint('<=', 1000)
+            cnx.execute('INSERT CWConstraint X: X value %(v)s, X cstrtype CT, '
+                        'EDEF constrained_by X WHERE CT name %(ct)s, EDEF eid %(x)s',
+                        {'ct': cstr3.__class__.__name__, 'v': cstr3.serialize(), 'x': rdef.eid})
+            cnx.commit()
+            self.assertCountEqual(rdef.constraints, [cstr, cstr3])
+
+
 if __name__ == '__main__':
     unittest_main()
--- a/hooks/test/unittest_syncsession.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/hooks/test/unittest_syncsession.py	Thu Dec 10 12:34:15 2015 +0100
@@ -22,6 +22,8 @@
   syncschema.py hooks are mostly tested in server/test/unittest_migrations.py
 """
 
+from six import text_type
+
 from cubicweb import ValidationError
 from cubicweb.devtools.testlib import CubicWebTC
 
@@ -32,13 +34,13 @@
             with self.assertRaises(ValidationError) as cm:
                 req.execute('INSERT CWProperty X: X pkey "bla.bla", '
                             'X value "hop", X for_user U')
-            cm.exception.translate(unicode)
+            cm.exception.translate(text_type)
             self.assertEqual(cm.exception.errors,
                              {'pkey-subject': 'unknown property key bla.bla'})
 
             with self.assertRaises(ValidationError) as cm:
                 req.execute('INSERT CWProperty X: X pkey "bla.bla", X value "hop"')
-            cm.exception.translate(unicode)
+            cm.exception.translate(text_type)
             self.assertEqual(cm.exception.errors,
                              {'pkey-subject': 'unknown property key bla.bla'})
 
--- a/hooks/workflow.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/hooks/workflow.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,7 +18,7 @@
 """Core hooks: workflow related hooks"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from datetime import datetime
 
@@ -355,4 +355,3 @@
         typewf = entity.cw_adapt_to('IWorkflowable').cwetype_workflow()
         if typewf is not None:
             _WorkflowChangedOp(self._cw, eid=self.eidfrom, wfeid=typewf.eid)
-
--- a/hooks/zmq.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/hooks/zmq.py	Thu Dec 10 12:34:15 2015 +0100
@@ -48,5 +48,3 @@
         for address in address_sub:
             self.repo.app_instances_bus.add_subscriber(address)
         self.repo.app_instances_bus.start()
-
-
--- a/i18n.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/i18n.py	Thu Dec 10 12:34:15 2015 +0100
@@ -16,6 +16,7 @@
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """Some i18n/gettext utilities."""
+from __future__ import print_function
 
 __docformat__ = "restructuredtext en"
 
@@ -24,6 +25,8 @@
 from os.path import join, basename, splitext, exists
 from glob import glob
 
+from six import PY2
+
 from cubicweb.toolsutils import create_dir
 
 def extract_from_tal(files, output_file):
@@ -39,10 +42,10 @@
 
 def add_msg(w, msgid, msgctx=None):
     """write an empty pot msgid definition"""
-    if isinstance(msgid, unicode):
+    if PY2 and isinstance(msgid, unicode):
         msgid = msgid.encode('utf-8')
     if msgctx:
-        if isinstance(msgctx, unicode):
+        if PY2 and isinstance(msgctx, unicode):
             msgctx = msgctx.encode('utf-8')
         w('msgctxt "%s"\n' % msgctx)
     msgid = msgid.replace('"', r'\"').splitlines()
@@ -80,7 +83,7 @@
     """
     from subprocess import CalledProcessError
     from logilab.common.fileutils import ensure_fs_mode
-    print '-> compiling message catalogs to %s' % destdir
+    print('-> compiling message catalogs to %s' % destdir)
     errors = []
     for lang in langs:
         langdir = join(destdir, lang, 'LC_MESSAGES')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jshintrc	Thu Dec 10 12:34:15 2015 +0100
@@ -0,0 +1,115 @@
+{
+    // --------------------------------------------------------------------
+    // JSHint Configuration, Strict Edition
+    // --------------------------------------------------------------------
+    //
+    // This is a options template for [JSHint][1], using [JSHint example][2]
+    // and [Ory Band's example][3] as basis and setting config values to
+    // be most strict:
+    //
+    // * set all enforcing options to true
+    // * set all relaxing options to false
+    // * set all environment options to false, except the browser value
+    // * set all JSLint legacy options to false
+    //
+    // [1]: http://www.jshint.com/
+    // [2]: https://github.com/jshint/node-jshint/blob/master/example/config.json
+    // [3]: https://github.com/oryband/dotfiles/blob/master/jshintrc
+    //
+    // @author http://michael.haschke.biz/
+    // @license http://unlicense.org/
+
+    // == Enforcing Options ===============================================
+    //
+    // These options tell JSHint to be more strict towards your code. Use
+    // them if you want to allow only a safe subset of JavaScript, very
+    // useful when your codebase is shared with a big number of developers
+    // with different skill levels.
+
+    "bitwise"       : true,     // Prohibit bitwise operators (&, |, ^, etc.).
+    "curly"         : true,     // Require {} for every new block or scope.
+    "eqeqeq"        : true,     // Require triple equals i.e. `===`.
+    "forin"         : true,     // Tolerate `for in` loops without `hasOwnPrototype`.
+    "immed"         : true,     // Require immediate invocations to be wrapped in parens e.g. `( function(){}() );`
+    "latedef"       : true,     // Prohibit variable use before definition.
+    "newcap"        : true,     // Require capitalization of all constructor functions e.g. `new F()`.
+    "noarg"         : true,     // Prohibit use of `arguments.caller` and `arguments.callee`.
+    "noempty"       : true,     // Prohibit use of empty blocks.
+    "nonew"         : true,     // Prohibit use of constructors for side-effects.
+    "plusplus"      : true,     // Prohibit use of `++` & `--`.
+    "regexp"        : true,     // Prohibit `.` and `[^...]` in regular expressions.
+    "undef"         : true,     // Require all non-global variables be declared before they are used.
+    "strict"        : true,     // Require `use strict` pragma in every file.
+    "trailing"      : true,     // Prohibit trailing whitespaces.
+    
+    // == Relaxing Options ================================================
+    //
+    // These options allow you to suppress certain types of warnings. Use
+    // them only if you are absolutely positive that you know what you are
+    // doing.
+    
+    "asi"           : false,    // Tolerate Automatic Semicolon Insertion (no semicolons).
+    "boss"          : false,    // Tolerate assignments inside if, for & while. Usually conditions & loops are for comparison, not assignments.
+    "debug"         : false,    // Allow debugger statements e.g. browser breakpoints.
+    "eqnull"        : false,    // Tolerate use of `== null`.
+    "es5"           : false,    // Allow EcmaScript 5 syntax.
+    "esnext"        : false,    // Allow ES.next specific features such as `const` and `let`.
+    "evil"          : false,    // Tolerate use of `eval`.
+    "expr"          : false,    // Tolerate `ExpressionStatement` as Programs.
+    "funcscope"     : false,    // Tolerate declarations of variables inside of control structures while accessing them later from the outside.
+    "globalstrict"  : false,    // Allow global "use strict" (also enables 'strict').
+    "iterator"      : false,    // Allow usage of __iterator__ property.
+    "lastsemic"     : false,    // Tolerat missing semicolons when the it is omitted for the last statement in a one-line block.
+    "laxbreak"      : false,    // Tolerate unsafe line breaks e.g. `return [\n] x` without semicolons.
+    "laxcomma"      : false,    // Suppress warnings about comma-first coding style.
+    "loopfunc"      : false,    // Allow functions to be defined within loops.
+    "multistr"      : false,    // Tolerate multi-line strings.
+    "onecase"       : false,    // Tolerate switches with just one case.
+    "proto"         : false,    // Tolerate __proto__ property. This property is deprecated.
+    "regexdash"     : false,    // Tolerate unescaped last dash i.e. `[-...]`.
+    "scripturl"     : false,    // Tolerate script-targeted URLs.
+    "smarttabs"     : false,    // Tolerate mixed tabs and spaces when the latter are used for alignmnent only.
+    "shadow"        : false,    // Allows re-define variables later in code e.g. `var x=1; x=2;`.
+    "sub"           : false,    // Tolerate all forms of subscript notation besides dot notation e.g. `dict['key']` instead of `dict.key`.
+    "supernew"      : false,    // Tolerate `new function () { ... };` and `new Object;`.
+    "validthis"     : false,    // Tolerate strict violations when the code is running in strict mode and you use this in a non-constructor function.
+    
+    // == Environments ====================================================
+    //
+    // These options pre-define global variables that are exposed by
+    // popular JavaScript libraries and runtime environments—such as
+    // browser or node.js.
+    
+    "browser"       : true,     // Standard browser globals e.g. `window`, `document`.
+    "couch"         : false,    // Enable globals exposed by CouchDB.
+    "devel"         : false,    // Allow development statements e.g. `console.log();`.
+    "dojo"          : false,    // Enable globals exposed by Dojo Toolkit.
+    "jquery"        : false,    // Enable globals exposed by jQuery JavaScript library.
+    "mootools"      : false,    // Enable globals exposed by MooTools JavaScript framework.
+    "node"          : false,    // Enable globals available when code is running inside of the NodeJS runtime environment.
+    "nonstandard"   : false,    // Define non-standard but widely adopted globals such as escape and unescape.
+    "prototypejs"   : false,    // Enable globals exposed by Prototype JavaScript framework.
+    "rhino"         : false,    // Enable globals available when your code is running inside of the Rhino runtime environment.
+    "wsh"           : false,    // Enable globals available when your code is running as a script for the Windows Script Host.
+    
+    // == JSLint Legacy ===================================================
+    //
+    // These options are legacy from JSLint. Aside from bug fixes they will
+    // not be improved in any way and might be removed at any point.
+    
+    "nomen"         : false,    // Prohibit use of initial or trailing underbars in names.
+    "onevar"        : false,    // Allow only one `var` statement per function.
+    "passfail"      : false,    // Stop on first error.
+    "white"         : false,    // Check against strict whitespace and indentation rules.
+    
+    // == Undocumented Options ============================================
+    //
+    // While I've found these options in [example1][2] and [example2][3]
+    // they are not described in the [JSHint Options documentation][4].
+    //
+    // [4]: http://www.jshint.com/options/
+
+    "maxerr"        : 100,      // Maximum errors before stopping.
+    "predef"        : [],       // Extra globals.
+    "indent"        : 4         // Specify indentation spacing
+}
--- a/mail.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/mail.py	Thu Dec 10 12:34:15 2015 +0100
@@ -28,16 +28,27 @@
 from email.utils import formatdate
 from socket import gethostname
 
+from six import PY2, PY3, text_type
+
+
 def header(ustring):
+    if PY3:
+        return Header(ustring, 'utf-8')
     return Header(ustring.encode('UTF-8'), 'UTF-8')
 
 def addrheader(uaddr, uname=None):
     # even if an email address should be ascii, encode it using utf8 since
     # automatic tests may generate non ascii email address
-    addr = uaddr.encode('UTF-8')
+    if PY2:
+        addr = uaddr.encode('UTF-8')
+    else:
+        addr = uaddr
     if uname:
-        return '%s <%s>' % (header(uname).encode(), addr)
-    return addr
+        val = '%s <%s>' % (header(uname).encode(), addr)
+    else:
+        val = addr
+    assert isinstance(val, str)  # bytes in py2, ascii-encoded unicode in py3
+    return val
 
 
 def construct_message_id(appid, eid, withtimestamp=True):
@@ -46,7 +57,7 @@
     else:
         addrpart = 'eid=%s' % eid
     # we don't want any equal sign nor trailing newlines
-    leftpart = b64encode(addrpart, '.-').rstrip().rstrip('=')
+    leftpart = b64encode(addrpart.encode('ascii'), b'.-').decode('ascii').rstrip().rstrip('=')
     return '<%s@%s.%s>' % (leftpart, appid, gethostname())
 
 
@@ -75,7 +86,7 @@
     to_addrs and cc_addrs are expected to be a list of email address without
     name
     """
-    assert type(content) is unicode, repr(content)
+    assert isinstance(content, text_type), repr(content)
     msg = MIMEText(content.encode('UTF-8'), 'plain', 'UTF-8')
     # safety: keep only the first newline
     try:
@@ -86,13 +97,13 @@
     if uinfo.get('email'):
         email = uinfo['email']
     elif config and config['sender-addr']:
-        email = unicode(config['sender-addr'])
+        email = text_type(config['sender-addr'])
     else:
         email = u''
     if uinfo.get('name'):
         name = uinfo['name']
     elif config and config['sender-name']:
-        name = unicode(config['sender-name'])
+        name = text_type(config['sender-name'])
     else:
         name = u''
     msg['From'] = addrheader(email, name)
--- a/md5crypt.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/md5crypt.py	Thu Dec 10 12:34:15 2015 +0100
@@ -38,31 +38,37 @@
  this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
 """
 
-MAGIC = '$1$'                        # Magic string
-ITOA64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+MAGIC = b'$1$'                        # Magic string
+ITOA64 = b"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
 
 from hashlib import md5 # pylint: disable=E0611
 
+from six import text_type, indexbytes
+from six.moves import range
+
+
 def to64 (v, n):
-    ret = ''
+    ret = bytearray()
     while (n - 1 >= 0):
         n = n - 1
-        ret = ret + ITOA64[v & 0x3f]
+        ret.append(ITOA64[v & 0x3f])
         v = v >> 6
     return ret
 
 def crypt(pw, salt):
-    if isinstance(pw, unicode):
+    if isinstance(pw, text_type):
         pw = pw.encode('utf-8')
+    if isinstance(salt, text_type):
+        salt = salt.encode('ascii')
     # Take care of the magic string if present
     if salt.startswith(MAGIC):
         salt = salt[len(MAGIC):]
     # salt can have up to 8 characters:
-    salt = salt.split('$', 1)[0]
+    salt = salt.split(b'$', 1)[0]
     salt = salt[:8]
     ctx = pw + MAGIC + salt
     final = md5(pw + salt + pw).digest()
-    for pl in xrange(len(pw), 0, -16):
+    for pl in range(len(pw), 0, -16):
         if pl > 16:
             ctx = ctx + final[:16]
         else:
@@ -71,7 +77,7 @@
     i = len(pw)
     while i:
         if i & 1:
-            ctx = ctx + chr(0)  #if ($i & 1) { $ctx->add(pack("C", 0)); }
+            ctx = ctx + b'\0'  #if ($i & 1) { $ctx->add(pack("C", 0)); }
         else:
             ctx = ctx + pw[0]
         i = i >> 1
@@ -79,8 +85,8 @@
     # The following is supposed to make
     # things run slower.
     # my question: WTF???
-    for i in xrange(1000):
-        ctx1 = ''
+    for i in range(1000):
+        ctx1 = b''
         if i & 1:
             ctx1 = ctx1 + pw
         else:
@@ -95,21 +101,21 @@
             ctx1 = ctx1 + pw
         final = md5(ctx1).digest()
     # Final xform
-    passwd = ''
-    passwd = passwd + to64((int(ord(final[0])) << 16)
-                           |(int(ord(final[6])) << 8)
-                           |(int(ord(final[12]))),4)
-    passwd = passwd + to64((int(ord(final[1])) << 16)
-                           |(int(ord(final[7])) << 8)
-                           |(int(ord(final[13]))), 4)
-    passwd = passwd + to64((int(ord(final[2])) << 16)
-                           |(int(ord(final[8])) << 8)
-                           |(int(ord(final[14]))), 4)
-    passwd = passwd + to64((int(ord(final[3])) << 16)
-                           |(int(ord(final[9])) << 8)
-                           |(int(ord(final[15]))), 4)
-    passwd = passwd + to64((int(ord(final[4])) << 16)
-                           |(int(ord(final[10])) << 8)
-                           |(int(ord(final[5]))), 4)
-    passwd = passwd + to64((int(ord(final[11]))), 2)
+    passwd = b''
+    passwd += to64((indexbytes(final, 0) << 16)
+                   |(indexbytes(final, 6) << 8)
+                   |(indexbytes(final, 12)),4)
+    passwd += to64((indexbytes(final, 1) << 16)
+                   |(indexbytes(final, 7) << 8)
+                   |(indexbytes(final, 13)), 4)
+    passwd += to64((indexbytes(final, 2) << 16)
+                   |(indexbytes(final, 8) << 8)
+                   |(indexbytes(final, 14)), 4)
+    passwd += to64((indexbytes(final, 3) << 16)
+                   |(indexbytes(final, 9) << 8)
+                   |(indexbytes(final, 15)), 4)
+    passwd += to64((indexbytes(final, 4) << 16)
+                   |(indexbytes(final, 10) << 8)
+                   |(indexbytes(final, 5)), 4)
+    passwd += to64((indexbytes(final, 11)), 2)
     return passwd
--- a/migration.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/migration.py	Thu Dec 10 12:34:15 2015 +0100
@@ -16,6 +16,7 @@
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """utilities for instances migration"""
+from __future__ import print_function
 
 __docformat__ = "restructuredtext en"
 
@@ -25,6 +26,9 @@
 import tempfile
 from os.path import exists, join, basename, splitext
 from itertools import chain
+from warnings import warn
+
+from six import string_types
 
 from logilab.common import IGNORED_EXTENSIONS
 from logilab.common.decorators import cached
@@ -49,7 +53,7 @@
     assert fromversion <= toversion, (fromversion, toversion)
     if not exists(directory):
         if not quiet:
-            print directory, "doesn't exists, no migration path"
+            print(directory, "doesn't exists, no migration path")
         return []
     if fromversion == toversion:
         return []
@@ -93,9 +97,9 @@
             stream = open(scriptpath)
             scriptcontent = stream.read()
             stream.close()
-            print
-            print scriptcontent
-            print
+            print()
+            print(scriptcontent)
+            print()
         else:
             return True
 
@@ -139,9 +143,6 @@
             raise
         raise AttributeError(name)
 
-    def repo_connect(self):
-        return self.config.repository()
-
     def migrate(self, vcconf, toupgrade, options):
         """upgrade the given set of cubes
 
@@ -243,7 +244,7 @@
         # avoid '_' to be added to builtins by sys.display_hook
         def do_not_add___to_builtins(obj):
             if obj is not None:
-                print repr(obj)
+                print(repr(obj))
         sys.displayhook = do_not_add___to_builtins
         local_ctx = self._create_context()
         try:
@@ -349,7 +350,16 @@
             else:
                 pyname = splitext(basename(migrscript))[0]
             scriptlocals['__name__'] = pyname
-            execfile(migrscript, scriptlocals)
+            with open(migrscript, 'rb') as fobj:
+                fcontent = fobj.read()
+            try:
+                code = compile(fcontent, migrscript, 'exec')
+            except SyntaxError:
+                # try without print_function
+                code = compile(fcontent, migrscript, 'exec', 0, True)
+                warn('[3.22] script %r should be updated to work with print_function'
+                     % migrscript, DeprecationWarning)
+            exec(code, scriptlocals)
             if funcname is not None:
                 try:
                     func = scriptlocals[funcname]
@@ -399,7 +409,7 @@
         """modify the list of used cubes in the in-memory config
         returns newly inserted cubes, including dependencies
         """
-        if isinstance(cubes, basestring):
+        if isinstance(cubes, string_types):
             cubes = (cubes,)
         origcubes = self.config.cubes()
         newcubes = [p for p in self.config.expand_cubes(cubes)
@@ -454,6 +464,10 @@
 
 
 def version_strictly_lower(a, b):
+    if a is None:
+        return True
+    if b is None:
+        return False
     if a:
         a = Version(a)
     if b:
@@ -491,8 +505,8 @@
             self.dependencies[cube] = dict(self.config.cube_dependencies(cube))
             self.dependencies[cube]['cubicweb'] = self.config.cube_depends_cubicweb_version(cube)
         # compute reverse dependencies
-        for cube, dependencies in self.dependencies.iteritems():
-            for name, constraint in dependencies.iteritems():
+        for cube, dependencies in self.dependencies.items():
+            for name, constraint in dependencies.items():
                 self.reverse_dependencies.setdefault(name,set())
                 if constraint:
                     try:
@@ -522,9 +536,9 @@
                     elif op == None:
                         continue
                     else:
-                        print ('unable to handle %s in %s, set to `%s %s` '
-                               'but currently up to `%s %s`' %
-                               (cube, source, oper, version, op, ver))
+                        print('unable to handle %s in %s, set to `%s %s` '
+                              'but currently up to `%s %s`' %
+                              (cube, source, oper, version, op, ver))
             # "solve" constraint satisfaction problem
             if cube not in self.cubes:
                 self.errors.append( ('add', cube, version, source) )
@@ -536,4 +550,4 @@
                 elif oper is None:
                     pass # no constraint on version
                 else:
-                    print 'unknown operator', oper
+                    print('unknown operator', oper)
--- a/misc/cwfs/cwfs.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/misc/cwfs/cwfs.py	Thu Dec 10 12:34:15 2015 +0100
@@ -80,17 +80,17 @@
         self._restrictions = []
 
     def parse(self) :
-        self._entity = self._components.next()
+        self._entity = next(self._components)
         try:
             self.process_entity()
         except StopIteration :
             pass
 
     def process_entity(self) :
-        _next = self._components.next()
+        _next = next(self._components)
         if _next in self.schema.get_attrs(self._entity) :
             self._attr = _next
-            _next = self._components.next()
+            _next = next(self._components)
             self._restrictions.append( (self._entity, self._attr, _next) )
             self._attr = None
             self._rel = None
@@ -136,7 +136,7 @@
 
     def parse(self):
         self._var = self._alphabet.pop(0)
-        self._e_type = self._components.next()
+        self._e_type = next(self._components)
         e_type = self._e_type.capitalize()
         self._restrictions.append('%s is %s' % (self._var, e_type))
         try:
@@ -146,11 +146,11 @@
         return 'Any %s WHERE %s' % (self._var, ', '.join(self._restrictions))
 
     def process_entity(self) :
-        _next = self._components.next()
+        _next = next(self._components)
         if _next in self.schema.get_attrs(self._e_type) :
             attr = _next
             try:
-                _next = self._components.next()
+                _next = next(self._components)
                 self._restrictions.append('%s %s %s' % (self._var, attr, _next))
             except StopIteration:
                 a_var = self._alphabet.pop(0)
@@ -163,7 +163,7 @@
             self._restrictions.append('%s %s %s' % (self._var, rel, r_var))
             self._var = r_var
             try:
-                _next = self._components.next()
+                _next = next(self._components)
                 self._restrictions.append('%s is %s' % (r_var, _next.capitalize()))
             except StopIteration:
                 raise
@@ -173,4 +173,3 @@
 def to_rql(path) :
     p = SytPathParser(SCHEMA,path)
     return p.parse()
-
--- a/misc/cwfs/cwfs_test.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/misc/cwfs/cwfs_test.py	Thu Dec 10 12:34:15 2015 +0100
@@ -30,7 +30,7 @@
     sections = []
     buffer = ""
     in_section = False
-    for line in file(filename) :
+    for line in open(filename) :
         if line.startswith('Test::'):
             in_section = True
             buffer = ""
--- a/misc/cwzope/cwzope.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/misc/cwzope/cwzope.py	Thu Dec 10 12:34:15 2015 +0100
@@ -48,4 +48,3 @@
         cnx = connect(user, password, host, database, group)
         CNX_CACHE[key] = cnx
         return cnx
-
--- a/misc/migration/3.10.0_Any.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/misc/migration/3.10.0_Any.py	Thu Dec 10 12:34:15 2015 +0100
@@ -1,3 +1,5 @@
+from six import text_type
+
 from cubicweb.server.session import hooks_control
 
 for uri, cfg in config.read_sources_file().items():
@@ -24,7 +26,7 @@
     repo.sources_by_uri.pop(uri)
     config = u'\n'.join('%s=%s' % (key, value) for key, value in cfg.items()
                         if key != 'adapter' and value is not None)
-    create_entity('CWSource', name=unicode(uri), type=unicode(cfg['adapter']),
+    create_entity('CWSource', name=text_type(uri), type=text_type(cfg['adapter']),
                   config=config)
 commit()
 
@@ -33,4 +35,3 @@
              'X pkey ~= "boxes.%" OR '
              'X pkey ~= "contentnavigation.%"').entities():
     x.cw_set(pkey=u'ctxcomponents.' + x.pkey.split('.', 1)[1])
-
--- a/misc/migration/3.14.0_Any.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/misc/migration/3.14.0_Any.py	Thu Dec 10 12:34:15 2015 +0100
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 config['rql-cache-size'] = config['rql-cache-size'] * 10
 
 add_entity_type('CWDataImport')
@@ -10,4 +12,4 @@
     mainvars = guess_rrqlexpr_mainvars(expression)
     yamscstr = CONSTRAINTS[rqlcstr.type](expression, mainvars)
     rqlcstr.cw_set(value=yamscstr.serialize())
-    print 'updated', rqlcstr.type, rqlcstr.value.strip()
+    print('updated', rqlcstr.type, rqlcstr.value.strip())
--- a/misc/migration/3.15.4_Any.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/misc/migration/3.15.4_Any.py	Thu Dec 10 12:34:15 2015 +0100
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 from logilab.common.shellutils import generate_password
 from cubicweb.server.utils import crypt_password
 
@@ -5,7 +7,7 @@
     salt = user.upassword.getvalue()
     if crypt_password('', salt) == salt:
         passwd = generate_password()
-        print 'setting random password for user %s' % user.login
+        print('setting random password for user %s' % user.login)
         user.set_attributes(upassword=passwd)
 
 commit()
--- a/misc/migration/3.21.0_Any.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/misc/migration/3.21.0_Any.py	Thu Dec 10 12:34:15 2015 +0100
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 from cubicweb.schema import PURE_VIRTUAL_RTYPES
 from cubicweb.server.schema2sql import rschema_has_table
 
@@ -27,7 +29,7 @@
                 '    SELECT eid FROM entities) AS eids' % args,
                 ask_confirm=False)[0][0]
     if count:
-        print '%s references %d unknown entities, deleting' % (rschema, count)
+        print('%s references %d unknown entities, deleting' % (rschema, count))
         sql('DELETE FROM %(r)s_relation '
             'WHERE eid_from IN (SELECT eid_from FROM %(r)s_relation EXCEPT SELECT eid FROM entities)' % args)
         sql('DELETE FROM %(r)s_relation '
@@ -65,14 +67,14 @@
             broken_eids = sql('SELECT cw_eid FROM cw_%(e)s WHERE cw_%(r)s IS NULL' % args,
                               ask_confirm=False)
             if broken_eids:
-                print 'Required relation %(e)s.%(r)s missing' % args
+                print('Required relation %(e)s.%(r)s missing' % args)
                 args['eids'] = ', '.join(str(eid) for eid, in broken_eids)
                 rql('DELETE %(e)s X WHERE X eid IN (%(eids)s)' % args)
             broken_eids = sql('SELECT cw_eid FROM cw_%(e)s WHERE cw_%(r)s IN (SELECT cw_%(r)s FROM cw_%(e)s '
                               'EXCEPT SELECT eid FROM entities)' % args,
                               ask_confirm=False)
             if broken_eids:
-                print 'Required relation %(e)s.%(r)s references unknown objects, deleting subject entities' % args
+                print('Required relation %(e)s.%(r)s references unknown objects, deleting subject entities' % args)
                 args['eids'] = ', '.join(str(eid) for eid, in broken_eids)
                 rql('DELETE %(e)s X WHERE X eid IN (%(eids)s)' % args)
         else:
@@ -81,7 +83,7 @@
                    '  EXCEPT'
                    '    SELECT eid FROM entities) AS eids' % args,
                    ask_confirm=False)[0][0]:
-                print '%(e)s.%(r)s references unknown entities, deleting relation' % args
+                print('%(e)s.%(r)s references unknown entities, deleting relation' % args)
                 sql('UPDATE cw_%(e)s SET cw_%(r)s = NULL WHERE cw_%(r)s IS NOT NULL AND cw_%(r)s IN '
                     '(SELECT cw_%(r)s FROM cw_%(e)s EXCEPT SELECT eid FROM entities)' % args)
 
@@ -104,7 +106,7 @@
            '  EXCEPT'
            '    SELECT eid FROM entities) AS eids' % args,
            ask_confirm=False)[0][0]:
-        print '%(e)s has nonexistent entities, deleting' % args
+        print('%(e)s has nonexistent entities, deleting' % args)
         sql('DELETE FROM cw_%(e)s WHERE cw_eid IN '
             '(SELECT cw_eid FROM cw_%(e)s EXCEPT SELECT eid FROM entities)' % args)
     args['c'] = 'cw_%(e)s_cw_eid_fkey' % args
--- a/misc/migration/3.8.5_Any.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/misc/migration/3.8.5_Any.py	Thu Dec 10 12:34:15 2015 +0100
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 def migrate_varchar_to_nvarchar():
     dbdriver  = config.system_source_config['db-driver']
     if dbdriver != "sqlserver2005":
@@ -52,7 +54,7 @@
 
 
     for statement in generated_statements:
-        print statement
+        print(statement)
         sql(statement, ask_confirm=False)
     commit()
 
--- a/misc/migration/bootstrapmigration_repository.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/misc/migration/bootstrapmigration_repository.py	Thu Dec 10 12:34:15 2015 +0100
@@ -19,6 +19,9 @@
 
 it should only include low level schema changes
 """
+from __future__ import print_function
+
+from six import text_type
 
 from cubicweb import ConfigurationError
 from cubicweb.server.session import hooks_control
@@ -77,8 +80,8 @@
         sql('ALTER TABLE "entities" DROP COLUMN "mtime"')
         sql('ALTER TABLE "entities" DROP COLUMN "source"')
     except: # programming error, already migrated
-        print "Failed to drop mtime or source database columns"
-        print "'entities' table of the database has probably been already updated"
+        print("Failed to drop mtime or source database columns")
+        print("'entities' table of the database has probably been already updated")
 
     commit()
 
@@ -101,7 +104,7 @@
     driver = config.system_source_config['db-driver']
     if not (driver == 'postgres' or driver.startswith('sqlserver')):
         import sys
-        print >>sys.stderr, 'This migration is not supported for backends other than sqlserver or postgres (yet).'
+        print('This migration is not supported for backends other than sqlserver or postgres (yet).', file=sys.stderr)
         sys.exit(1)
 
     add_relation_definition('CWAttribute', 'add_permission', 'CWGroup')
@@ -148,7 +151,7 @@
                 default = yams.DATE_FACTORY_MAP[atype](default)
         else:
             assert atype == 'String', atype
-            default = unicode(default)
+            default = text_type(default)
         return Binary.zpickle(default)
 
     dbh = repo.system_source.dbhelper
@@ -196,7 +199,7 @@
                                                 (rschema.type, ','.join(subjects))))
             if martians:
                 martians = ','.join(martians)
-                print 'deleting broken relations %s for eids %s' % (rschema.type, martians)
+                print('deleting broken relations %s for eids %s' % (rschema.type, martians))
                 sql('DELETE FROM %s_relation WHERE eid_from IN (%s) OR eid_to IN (%s)' % (rschema.type, martians, martians))
             with session.deny_all_hooks_but():
                 rql('SET X %(r)s Y WHERE Y %(r)s X, NOT X %(r)s Y' % {'r': rschema.type})
@@ -219,20 +222,20 @@
     if driver == 'postgres':
         for indexname, in sql('select indexname from pg_indexes'):
             if indexname.startswith('unique_'):
-                print 'dropping index', indexname
+                print('dropping index', indexname)
                 sql('DROP INDEX %s' % indexname)
         commit()
     elif driver.startswith('sqlserver'):
         for viewname, in sql('select name from sys.views'):
             if viewname.startswith('utv_'):
-                print 'dropping view (index should be cascade-deleted)', viewname
+                print('dropping view (index should be cascade-deleted)', viewname)
                 sql('DROP VIEW %s' % viewname)
         commit()
 
     # recreate the constraints, hook will lead to low-level recreation
     for eschema in sorted(schema.entities()):
         if eschema._unique_together:
-            print 'recreate unique indexes for', eschema
+            print('recreate unique indexes for', eschema)
             rql_args = schemaserial.uniquetogether2rqls(eschema)
             for rql, args in rql_args:
                 args['x'] = eschema.eid
@@ -243,10 +246,10 @@
     for rschema in sorted(schema.relations()):
         if rschema.final:
             if rschema.type in fsschema:
-                print 'sync perms for', rschema.type
+                print('sync perms for', rschema.type)
                 sync_schema_props_perms(rschema.type, syncprops=False, ask_confirm=False, commit=False)
             else:
-                print 'WARNING: attribute %s missing from fs schema' % rschema.type
+                print('WARNING: attribute %s missing from fs schema' % rschema.type)
     commit()
 
 if applcubicwebversion < (3, 17, 0) and cubicwebversion >= (3, 17, 0):
@@ -298,7 +301,7 @@
     with hooks_control(session, session.HOOKS_ALLOW_ALL, 'integrity'):
         for rschema in repo.schema.relations():
             rpermsdict = permsdict.get(rschema.eid, {})
-            for rdef in rschema.rdefs.itervalues():
+            for rdef in rschema.rdefs.values():
                 for action in rdef.ACTIONS:
                     actperms = []
                     for something in rpermsdict.get(action == 'update' and 'add' or action, ()):
--- a/misc/migration/postcreate.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/misc/migration/postcreate.py	Thu Dec 10 12:34:15 2015 +0100
@@ -16,13 +16,19 @@
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """cubicweb post creation script, set user's workflow"""
+from __future__ import print_function
+
+from six import text_type
+
+from cubicweb import _
+
 
 # insert versions
 create_entity('CWProperty', pkey=u'system.version.cubicweb',
-              value=unicode(config.cubicweb_version()))
+              value=text_type(config.cubicweb_version()))
 for cube in config.cubes():
     create_entity('CWProperty', pkey=u'system.version.%s' % cube.lower(),
-                  value=unicode(config.cube_version(cube)))
+                  value=text_type(config.cube_version(cube)))
 
 # some entities have been added before schema entities, fix the 'is' and
 # 'is_instance_of' relations
@@ -30,8 +36,8 @@
     sql('INSERT INTO %s_relation '
         'SELECT X.eid, ET.cw_eid FROM entities as X, cw_CWEType as ET '
         'WHERE X.type=ET.cw_name AND NOT EXISTS('
-        '      SELECT 1 from is_relation '
-        '      WHERE eid_from=X.eid AND eid_to=ET.cw_eid)' % rtype)
+        '      SELECT 1 from %s_relation '
+        '      WHERE eid_from=X.eid AND eid_to=ET.cw_eid)' % (rtype, rtype))
 
 # user workflow
 userwf = add_workflow(_('default user workflow'), 'CWUser')
@@ -46,11 +52,11 @@
 if hasattr(config, 'anonymous_user'):
     anonlogin, anonpwd = config.anonymous_user()
     if anonlogin == session.user.login:
-        print 'you are using a manager account as anonymous user.'
-        print 'Hopefully this is not a production instance...'
+        print('you are using a manager account as anonymous user.')
+        print('Hopefully this is not a production instance...')
     elif anonlogin:
         from cubicweb.server import create_user
-        create_user(session, unicode(anonlogin), anonpwd, u'guests')
+        create_user(session, text_type(anonlogin), anonpwd, u'guests')
 
 # need this since we already have at least one user in the database (the default admin)
 for user in rql('Any X WHERE X is CWUser').entities():
--- a/misc/scripts/cwuser_ldap2system.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/misc/scripts/cwuser_ldap2system.py	Thu Dec 10 12:34:15 2015 +0100
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 import base64
 from cubicweb.server.utils import crypt_password
 
@@ -20,10 +22,10 @@
 rset = sql("SELECT eid,type,source,extid,mtime FROM entities WHERE source!='system'", ask_confirm=False)
 for eid, type, source, extid, mtime in rset:
     if type != 'CWUser':
-        print "don't know what to do with entity type", type
+        print("don't know what to do with entity type", type)
         continue
     if not source.lower().startswith('ldap'):
-        print "don't know what to do with source type", source
+        print("don't know what to do with source type", source)
         continue
     extid = base64.decodestring(extid)
     ldapinfos = [x.strip().split('=') for x in extid.split(',')]
@@ -33,7 +35,7 @@
     args = dict(eid=eid, type=type, source=source, login=login,
                 firstname=firstname, surname=surname, mtime=mtime,
                 pwd=dbhelper.binary_value(crypt_password('toto')))
-    print args
+    print(args)
     sql(insert, args)
     sql(update, args)
 
--- a/misc/scripts/detect_cycle.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/misc/scripts/detect_cycle.py	Thu Dec 10 12:34:15 2015 +0100
@@ -1,9 +1,10 @@
+from __future__ import print_function
 
 try:
     rtype, = __args__
 except ValueError:
-    print 'USAGE: cubicweb-ctl shell <instance> detect_cycle.py -- <relation type>'
-    print
+    print('USAGE: cubicweb-ctl shell <instance> detect_cycle.py -- <relation type>')
+    print()
 
 graph = {}
 for fromeid, toeid in rql('Any X,Y WHERE X %s Y' % rtype):
@@ -12,4 +13,4 @@
 from logilab.common.graph import get_cycles
 
 for cycle in get_cycles(graph):
-    print 'cycle', '->'.join(str(n) for n in cycle)
+    print('cycle', '->'.join(str(n) for n in cycle))
--- a/misc/scripts/ldap_change_base_dn.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/misc/scripts/ldap_change_base_dn.py	Thu Dec 10 12:34:15 2015 +0100
@@ -1,10 +1,12 @@
+from __future__ import print_function
+
 from base64 import b64decode, b64encode
 try:
     uri, newdn = __args__
 except ValueError:
-    print 'USAGE: cubicweb-ctl shell <instance> ldap_change_base_dn.py -- <ldap source uri> <new dn>'
-    print
-    print 'you should not have updated your sources file yet'
+    print('USAGE: cubicweb-ctl shell <instance> ldap_change_base_dn.py -- <ldap source uri> <new dn>')
+    print()
+    print('you should not have updated your sources file yet')
 
 olddn = repo.sources_by_uri[uri].config['user-base-dn']
 
@@ -16,9 +18,9 @@
     olduserdn = b64decode(extid)
     newuserdn = olduserdn.replace(olddn, newdn)
     if newuserdn != olduserdn:
-        print olduserdn, '->', newuserdn
+        print(olduserdn, '->', newuserdn)
         sql("UPDATE entities SET extid='%s' WHERE eid=%s" % (b64encode(newuserdn), eid))
 
 commit()
 
-print 'you can now update the sources file to the new dn and restart the instance'
+print('you can now update the sources file to the new dn and restart the instance')
--- a/misc/scripts/ldapuser2ldapfeed.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/misc/scripts/ldapuser2ldapfeed.py	Thu Dec 10 12:34:15 2015 +0100
@@ -2,6 +2,8 @@
 
 Once this script is run, execute c-c db-check to cleanup relation tables.
 """
+from __future__ import print_function
+
 import sys
 from collections import defaultdict
 from logilab.common.shellutils import generate_password
@@ -14,12 +16,12 @@
           ' on the command line)')
     sys.exit(1)
 except KeyError:
-    print '%s is not an active source' % source_name
+    print('%s is not an active source' % source_name)
     sys.exit(1)
 
 # check source is reachable before doing anything
 if not source.get_connection().cnx:
-    print '%s is not reachable. Fix this before running this script' % source_name
+    print('%s is not reachable. Fix this before running this script' % source_name)
     sys.exit(1)
 
 raw_input('Ensure you have shutdown all instances of this application before continuing.'
@@ -31,7 +33,7 @@
 from cubicweb.server.edition import EditedEntity
 
 
-print '******************** backport entity content ***************************'
+print('******************** backport entity content ***************************')
 
 todelete = defaultdict(list)
 extids = set()
@@ -39,17 +41,17 @@
 for entity in rql('Any X WHERE X cw_source S, S eid %(s)s', {'s': source.eid}).entities():
     etype = entity.cw_etype
     if not source.support_entity(etype):
-        print "source doesn't support %s, delete %s" % (etype, entity.eid)
+        print("source doesn't support %s, delete %s" % (etype, entity.eid))
         todelete[etype].append(entity)
         continue
     try:
         entity.complete()
     except Exception:
-        print '%s %s much probably deleted, delete it (extid %s)' % (
-            etype, entity.eid, entity.cw_metainformation()['extid'])
+        print('%s %s much probably deleted, delete it (extid %s)' % (
+            etype, entity.eid, entity.cw_metainformation()['extid']))
         todelete[etype].append(entity)
         continue
-    print 'get back', etype, entity.eid
+    print('get back', etype, entity.eid)
     entity.cw_edited = EditedEntity(entity, **entity.cw_attr_cache)
     if not entity.creation_date:
         entity.cw_edited['creation_date'] = datetime.now()
@@ -61,7 +63,7 @@
     if not entity.cwuri:
         entity.cw_edited['cwuri'] = '%s/?dn=%s' % (
             source.urls[0], extid.decode('utf-8', 'ignore'))
-    print entity.cw_edited
+    print(entity.cw_edited)
     if extid in extids:
         duplicates.append(extid)
         continue
@@ -73,13 +75,13 @@
 # only cleanup entities table, remaining stuff should be cleaned by a c-c
 # db-check to be run after this script
 if duplicates:
-    print 'found %s duplicate entries' % len(duplicates)
+    print('found %s duplicate entries' % len(duplicates))
     from pprint import pprint
     pprint(duplicates)
 
-print len(todelete), 'entities will be deleted'
-for etype, entities in todelete.iteritems():
-    print 'deleting', etype, [e.login for e in entities]
+print(len(todelete), 'entities will be deleted')
+for etype, entities in todelete.items():
+    print('deleting', etype, [e.login for e in entities])
     system_source.delete_info_multi(session, entities, source_name)
 
 
@@ -89,9 +91,8 @@
 
 
 if raw_input('Commit?') in 'yY':
-    print 'committing'
+    print('committing')
     commit()
 else:
     rollback()
-    print 'rolled back'
-
+    print('rolled back')
--- a/misc/scripts/pyroforge2datafeed.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/misc/scripts/pyroforge2datafeed.py	Thu Dec 10 12:34:15 2015 +0100
@@ -2,6 +2,8 @@
 
 Once this script is run, execute c-c db-check to cleanup relation tables.
 """
+from __future__ import print_function
+
 import sys
 
 try:
@@ -12,14 +14,14 @@
           ' on the command line)')
     sys.exit(1)
 except KeyError:
-    print '%s is not an active source' % source_name
+    print('%s is not an active source' % source_name)
     sys.exit(1)
 
 # check source is reachable before doing anything
 try:
     source.get_connection()._repo
 except AttributeError:
-    print '%s is not reachable. Fix this before running this script' % source_name
+    print('%s is not reachable. Fix this before running this script' % source_name)
     sys.exit(1)
 
 raw_input('Ensure you have shutdown all instances of this application before continuing.'
@@ -39,7 +41,7 @@
         ))
 
 
-print '******************** backport entity content ***************************'
+print('******************** backport entity content ***************************')
 
 from cubicweb.server import debugged
 todelete = {}
@@ -47,20 +49,20 @@
 for entity in rql('Any X WHERE X cw_source S, S eid %(s)s', {'s': source.eid}).entities():
         etype = entity.cw_etype
         if not source.support_entity(etype):
-            print "source doesn't support %s, delete %s" % (etype, entity.eid)
+            print("source doesn't support %s, delete %s" % (etype, entity.eid))
         elif etype in DONT_GET_BACK_ETYPES:
-            print 'ignore %s, delete %s' % (etype, entity.eid)
+            print('ignore %s, delete %s' % (etype, entity.eid))
         else:
             try:
                 entity.complete()
                 if not host in entity.cwuri:
-                    print 'SKIP foreign entity', entity.cwuri, source.config['base-url']
+                    print('SKIP foreign entity', entity.cwuri, source.config['base-url'])
                     continue
             except Exception:
-                print '%s %s much probably deleted, delete it (extid %s)' % (
-                    etype, entity.eid, entity.cw_metainformation()['extid'])
+                print('%s %s much probably deleted, delete it (extid %s)' % (
+                    etype, entity.eid, entity.cw_metainformation()['extid']))
             else:
-                print 'get back', etype, entity.eid
+                print('get back', etype, entity.eid)
                 entity.cw_edited = EditedEntity(entity, **entity.cw_attr_cache)
                 system_source.add_entity(session, entity)
                 sql("UPDATE entities SET asource=%(asource)s, source='system', extid=%(extid)s "
@@ -72,11 +74,11 @@
 
 # only cleanup entities table, remaining stuff should be cleaned by a c-c
 # db-check to be run after this script
-for entities in todelete.itervalues():
+for entities in todelete.values():
     system_source.delete_info_multi(session, entities, source_name)
 
 
-print '******************** backport mapping **********************************'
+print('******************** backport mapping **********************************')
 session.disable_hook_categories('cw.sources')
 mapping = []
 for mappart in rql('Any X,SCH WHERE X cw_schema SCH, X cw_for_source S, S eid %(s)s',
@@ -85,13 +87,13 @@
     if schemaent.cw_etype != 'CWEType':
         assert schemaent.cw_etype == 'CWRType'
         sch = schema._eid_index[schemaent.eid]
-        for rdef in sch.rdefs.itervalues():
+        for rdef in sch.rdefs.values():
             if not source.support_entity(rdef.subject) \
                     or not source.support_entity(rdef.object):
                 continue
             if rdef.subject in DONT_GET_BACK_ETYPES \
                     and rdef.object in DONT_GET_BACK_ETYPES:
-                print 'dont map', rdef
+                print('dont map', rdef)
                 continue
             if rdef.subject in DONT_GET_BACK_ETYPES:
                 options = u'action=link\nlinkattr=name'
@@ -105,7 +107,7 @@
                     roles = 'object',
                 else:
                     roles = 'subject',
-            print 'map', rdef, options, roles
+            print('map', rdef, options, roles)
             for role in roles:
                 mapping.append( (
                         (str(rdef.subject), str(rdef.rtype), str(rdef.object)),
--- a/misc/scripts/repair_file_1-9_migration.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/misc/scripts/repair_file_1-9_migration.py	Thu Dec 10 12:34:15 2015 +0100
@@ -4,13 +4,14 @@
 * on our intranet on July 07 2010
 * on our extranet on July 16 2010
 """
+from __future__ import print_function
 
 try:
     backupinstance, = __args__
 except ValueError:
-    print 'USAGE: cubicweb-ctl shell <instance> repair_file_1-9_migration.py -- <backup instance id>'
-    print
-    print 'you should restored the backup on a new instance, accessible through pyro'
+    print('USAGE: cubicweb-ctl shell <instance> repair_file_1-9_migration.py -- <backup instance id>')
+    print()
+    print('you should restored the backup on a new instance, accessible through pyro')
 
 from cubicweb import cwconfig, dbapi
 from cubicweb.server.session import hooks_control
@@ -32,20 +33,20 @@
                                    'XX from_entity YY, YY name "File")'):
         if rtype in ('is', 'is_instance_of'):
             continue
-        print rtype
+        print(rtype)
         for feid, xeid in backupcu.execute('Any F,X WHERE F %s X, F is IN (File,Image)' % rtype):
-            print 'restoring relation %s between file %s and %s' % (rtype, feid, xeid),
-            print rql('SET F %s X WHERE F eid %%(f)s, X eid %%(x)s, NOT F %s X' % (rtype, rtype),
-                      {'f': feid, 'x': xeid})
+            print('restoring relation %s between file %s and %s' % (rtype, feid, xeid), end=' ')
+            print(rql('SET F %s X WHERE F eid %%(f)s, X eid %%(x)s, NOT F %s X' % (rtype, rtype),
+                      {'f': feid, 'x': xeid}))
 
     for rtype, in backupcu.execute('DISTINCT Any RTN WHERE X relation_type RT, RT name RTN,'
                                    'X to_entity Y, Y name "Image", X is CWRelation, '
                                    'EXISTS(XX is CWRelation, XX relation_type RT, '
                                    'XX to_entity YY, YY name "File")'):
-        print rtype
+        print(rtype)
         for feid, xeid in backupcu.execute('Any F,X WHERE X %s F, F is IN (File,Image)' % rtype):
-            print 'restoring relation %s between %s and file %s' % (rtype, xeid, feid),
-            print rql('SET X %s F WHERE F eid %%(f)s, X eid %%(x)s, NOT X %s F' % (rtype, rtype),
-                      {'f': feid, 'x': xeid})
+            print('restoring relation %s between %s and file %s' % (rtype, xeid, feid), end=' ')
+            print(rql('SET X %s F WHERE F eid %%(f)s, X eid %%(x)s, NOT X %s F' % (rtype, rtype),
+                      {'f': feid, 'x': xeid}))
 
 commit()
--- a/misc/scripts/repair_splitbrain_ldapuser_source.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/misc/scripts/repair_splitbrain_ldapuser_source.py	Thu Dec 10 12:34:15 2015 +0100
@@ -14,6 +14,7 @@
 deciding to apply it for you. And then ADAPT it tou your needs.
 
 """
+from __future__ import print_function
 
 import base64
 from collections import defaultdict
@@ -28,12 +29,12 @@
           ' on the command line)')
     sys.exit(1)
 except KeyError:
-    print '%s is not an active source' % source_name
+    print('%s is not an active source' % source_name)
     sys.exit(1)
 
 # check source is reachable before doing anything
 if not source.get_connection().cnx:
-    print '%s is not reachable. Fix this before running this script' % source_name
+    print('%s is not reachable. Fix this before running this script' % source_name)
     sys.exit(1)
 
 def find_dupes():
@@ -52,11 +53,11 @@
     CWUser = schema['CWUser']
     for extid, eids in dupes.items():
         newest = eids.pop() # we merge everything on the newest
-        print 'merging ghosts of', extid, 'into', newest
+        print('merging ghosts of', extid, 'into', newest)
         # now we merge pairwise into the newest
         for old in eids:
             subst = {'old': old, 'new': newest}
-            print '  merging', old
+            print('  merging', old)
             gone_eids.append(old)
             for rschema in CWUser.subject_relations():
                 if rschema.final or rschema == 'identity':
@@ -83,24 +84,24 @@
         rollback()
         return
     commit() # XXX flushing operations is wanted rather than really committing
-    print 'clean up entities table'
+    print('clean up entities table')
     sql('DELETE FROM entities WHERE eid IN (%s)' % (', '.join(str(x) for x in gone_eids)))
     commit()
 
 def main():
     dupes = find_dupes()
     if not dupes:
-        print 'No duplicate user'
+        print('No duplicate user')
         return
 
-    print 'Found %s duplicate user instances' % len(dupes)
+    print('Found %s duplicate user instances' % len(dupes))
 
     while True:
-        print 'Fix or dry-run? (f/d)  ... or Ctrl-C to break out'
+        print('Fix or dry-run? (f/d)  ... or Ctrl-C to break out')
         answer = raw_input('> ')
         if answer.lower() not in 'fd':
             continue
-        print 'Please STOP THE APPLICATION INSTANCES (service or interactive), and press Return when done.'
+        print('Please STOP THE APPLICATION INSTANCES (service or interactive), and press Return when done.')
         raw_input('<I swear all running instances and workers of the application are stopped>')
         with hooks_control(session, session.HOOKS_DENY_ALL):
             merge_dupes(dupes, docommit=answer=='f')
--- a/multipart.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/multipart.py	Thu Dec 10 12:34:15 2015 +0100
@@ -41,14 +41,13 @@
 from wsgiref.headers import Headers
 import re, sys
 try:
-    from urlparse import parse_qs
-except ImportError: # pragma: no cover (fallback for Python 2.5)
-    from cgi import parse_qs
-try:
     from io import BytesIO
 except ImportError: # pragma: no cover (fallback for Python 2.5)
     from StringIO import StringIO as BytesIO
 
+from six import PY3, text_type
+from six.moves.urllib.parse import parse_qs
+
 ##############################################################################
 ################################ Helper & Misc ################################
 ##############################################################################
@@ -63,7 +62,7 @@
     """ A dict that remembers old values for each key """
     def __init__(self, *a, **k):
         self.dict = dict()
-        for k, v in dict(*a, **k).iteritems():
+        for k, v in dict(*a, **k).items():
             self[k] = v
 
     def __len__(self): return len(self.dict)
@@ -84,12 +83,12 @@
         return self.dict[key][index]
 
     def iterallitems(self):
-        for key, values in self.dict.iteritems():
+        for key, values in self.dict.items():
             for value in values:
                 yield key, value
 
 def tob(data, enc='utf8'): # Convert strings to bytes (py2 and py3)
-    return data.encode(enc) if isinstance(data, unicode) else data
+    return data.encode(enc) if isinstance(data, text_type) else data
 
 def copy_file(stream, target, maxread=-1, buffer_size=2*16):
     ''' Read from :stream and write to :target until :maxread or EOF. '''
@@ -397,17 +396,21 @@
                               'application/x-url-encoded'):
             mem_limit = kw.get('mem_limit', 2**20)
             if content_length > mem_limit:
-                raise MultipartError("Request to big. Increase MAXMEM.")
+                raise MultipartError("Request too big. Increase MAXMEM.")
             data = stream.read(mem_limit)
             if stream.read(1): # These is more that does not fit mem_limit
-                raise MultipartError("Request to big. Increase MAXMEM.")
+                raise MultipartError("Request too big. Increase MAXMEM.")
+            if PY3:
+                data = data.decode('ascii')
             data = parse_qs(data, keep_blank_values=True)
-            for key, values in data.iteritems():
+            for key, values in data.items():
                 for value in values:
-                    forms[key] = value.decode(charset)
+                    if PY3:
+                        forms[key] = value
+                    else:
+                        forms[key.decode(charset)] = value.decode(charset)
         else:
             raise MultipartError("Unsupported content type.")
     except MultipartError:
         if strict: raise
     return forms, files
-
--- a/predicates.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/predicates.py	Thu Dec 10 12:34:15 2015 +0100
@@ -24,6 +24,9 @@
 from warnings import warn
 from operator import eq
 
+from six import string_types, integer_types
+from six.moves import range
+
 from logilab.common.deprecation import deprecated
 from logilab.common.registry import Predicate, objectify_predicate, yes
 
@@ -106,7 +109,7 @@
             if accept_none is None:
                 accept_none = self.accept_none
             if not accept_none and \
-                   any(rset[i][col] is None for i in xrange(len(rset))):
+                   any(row[col] is None for row in rset):
                 return 0
             etypes = rset.column_types(col)
         else:
@@ -332,7 +335,7 @@
             # on rset containing several entity types, each row may be
             # individually adaptable, while the whole rset won't be if the
             # same adapter can't be used for each type
-            for row in xrange(len(kwargs['rset'])):
+            for row in range(len(kwargs['rset'])):
                 kwargs.setdefault('col', 0)
                 _score = super(adaptable, self).__call__(cls, req, row=row, **kwargs)
                 if not _score:
@@ -489,10 +492,13 @@
         page_size = kwargs.get('page_size')
         if page_size is None:
             page_size = req.form.get('page_size')
+            if page_size is not None:
+                try:
+                    page_size = int(page_size)
+                except ValueError:
+                    page_size = None
             if page_size is None:
                 page_size = req.property_value('navigation.page-size')
-            else:
-                page_size = int(page_size)
         if len(rset) <= (page_size*self.nbpages):
             return 0
         return self.nbpages
@@ -611,7 +617,7 @@
         super(is_instance, self).__init__(**kwargs)
         self.expected_etypes = expected_etypes
         for etype in self.expected_etypes:
-            assert isinstance(etype, basestring), etype
+            assert isinstance(etype, string_types), etype
 
     def __str__(self):
         return '%s(%s)' % (self.__class__.__name__,
@@ -671,7 +677,7 @@
             score = scorefunc(*args, **kwargs)
             if not score:
                 return 0
-            if isinstance(score, (int, long)):
+            if isinstance(score, integer_types):
                 return score
             return 1
         self.score_entity = intscore
@@ -828,7 +834,7 @@
 
 class has_related_entities(EntityPredicate):
     """Return 1 if entity support the specified relation and has some linked
-    entities by this relation , optionaly filtered according to the specified
+    entities by this relation , optionally filtered according to the specified
     target type.
 
     The relation is specified by the following initializer arguments:
@@ -1091,7 +1097,7 @@
     """
     if from_state_name is not None:
         warn("on_fire_transition's from_state_name argument is unused", DeprecationWarning)
-    if isinstance(tr_names, basestring):
+    if isinstance(tr_names, string_types):
         tr_names = set((tr_names,))
     def match_etype_and_transition(trinfo):
         # take care trinfo.transition is None when calling change_state
@@ -1291,7 +1297,7 @@
             raise ValueError("match_form_params() can't be called with both "
                              "positional and named arguments")
         if expected:
-            if len(expected) == 1 and not isinstance(expected[0], basestring):
+            if len(expected) == 1 and not isinstance(expected[0], string_types):
                 raise ValueError("match_form_params() positional arguments "
                                  "must be strings")
             super(match_form_params, self).__init__(*expected)
--- a/pylintext.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/pylintext.py	Thu Dec 10 12:34:15 2015 +0100
@@ -17,7 +17,7 @@
 def cubicweb_transform(module):
     # handle objectify_predicate decorator (and its former name until bw compat
     # is kept). Only look at module level functions, should be enough.
-    for assnodes in module.locals.itervalues():
+    for assnodes in module.locals.values():
         for node in assnodes:
             if isinstance(node, scoped_nodes.Function) and node.decorators:
                 for decorator in node.decorators.nodes:
@@ -48,4 +48,3 @@
 def register(linter):
     """called when loaded by pylint --load-plugins, nothing to do here"""
     MANAGER.register_transform(nodes.Module, cubicweb_transform)
-
--- a/repoapi.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/repoapi.py	Thu Dec 10 12:34:15 2015 +0100
@@ -17,21 +17,17 @@
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """Official API to access the content of a repository
 """
+from warnings import warn
+
+from six import add_metaclass
+
 from logilab.common.deprecation import class_deprecated
 
 from cubicweb.utils import parse_repo_uri
-from cubicweb import ConnectionError, AuthenticationError
+from cubicweb import AuthenticationError
 from cubicweb.server.session import Connection
 
 
-### private function for specific method ############################
-
-def _get_inmemory_repo(config, vreg=None):
-    from cubicweb.server.repository import Repository
-    from cubicweb.server.utils import TasksManager
-    return Repository(config, TasksManager(), vreg=vreg)
-
-
 ### public API ######################################################
 
 def get_repository(uri=None, config=None, vreg=None):
@@ -41,16 +37,11 @@
     The returned repository may be an in-memory repository or a proxy object
     using a specific RPC method, depending on the given URI.
     """
-    if uri is None:
-        return _get_inmemory_repo(config, vreg)
-
-    protocol, hostport, appid = parse_repo_uri(uri)
+    if uri is not None:
+        warn('[3.22] get_repository only wants a config')
 
-    if protocol == 'inmemory':
-        # me may have been called with a dummy 'inmemory://' uri ...
-        return _get_inmemory_repo(config, vreg)
-
-    raise ConnectionError('unknown protocol: `%s`' % protocol)
+    assert config is not None, 'get_repository(config=config)'
+    return config.repository(vreg)
 
 def connect(repo, login, **kwargs):
     """Take credential and return associated Connection.
@@ -75,6 +66,6 @@
     return connect(repo, anon_login, password=anon_password)
 
 
+@add_metaclass(class_deprecated)
 class ClientConnection(Connection):
-    __metaclass__ = class_deprecated
     __deprecation_warning__ = '[3.20] %(cls)s is deprecated, use Connection instead'
--- a/req.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/req.py	Thu Dec 10 12:34:15 2015 +0100
@@ -20,10 +20,10 @@
 __docformat__ = "restructuredtext en"
 
 from warnings import warn
-from urlparse import urlsplit, urlunsplit
-from urllib import quote as urlquote, unquote as urlunquote
 from datetime import time, datetime, timedelta
-from cgi import parse_qs, parse_qsl
+
+from six import PY2, PY3, text_type
+from six.moves.urllib.parse import parse_qs, parse_qsl, quote as urlquote, unquote as urlunquote, urlsplit, urlunsplit
 
 from logilab.common.decorators import cached
 from logilab.common.deprecation import deprecated
@@ -73,7 +73,7 @@
         # connection
         self.user = None
         self.local_perm_cache = {}
-        self._ = unicode
+        self._ = text_type
 
     def _set_user(self, orig_user):
         """set the user for this req_session_base
@@ -219,7 +219,7 @@
                 parts.append(
                     '%(varname)s %(attr)s X, '
                     '%(varname)s eid %%(reverse_%(attr)s)s'
-                    % {'attr': attr, 'varname': varmaker.next()})
+                    % {'attr': attr, 'varname': next(varmaker)})
             else:
                 assert attr in eschema.subjrels, \
                     '%s not in %s subject relations' % (attr, eschema)
@@ -300,7 +300,7 @@
     def build_url_params(self, **kwargs):
         """return encoded params to incorporate them in a URL"""
         args = []
-        for param, values in kwargs.iteritems():
+        for param, values in kwargs.items():
             if not isinstance(values, (list, tuple)):
                 values = (values,)
             for value in values:
@@ -313,7 +313,7 @@
         necessary encoding / decoding. Also it's designed to quote each
         part of a url path and so the '/' character will be encoded as well.
         """
-        if isinstance(value, unicode):
+        if PY2 and isinstance(value, unicode):
             quoted = urlquote(value.encode(self.encoding), safe=safe)
             return unicode(quoted, self.encoding)
         return urlquote(str(value), safe=safe)
@@ -324,6 +324,8 @@
         decoding is based on `self.encoding` which is the encoding
         used in `url_quote`
         """
+        if PY3:
+            return urlunquote(quoted)
         if isinstance(quoted, unicode):
             quoted = quoted.encode(self.encoding)
         try:
@@ -333,6 +335,10 @@
 
     def url_parse_qsl(self, querystring):
         """return a list of (key, val) found in the url quoted query string"""
+        if PY3:
+            for key, val in parse_qsl(querystring):
+                yield key, val
+            return
         if isinstance(querystring, unicode):
             querystring = querystring.encode(self.encoding)
         for key, val in parse_qsl(querystring):
@@ -348,12 +354,12 @@
 
         newparams may only be mono-valued.
         """
-        if isinstance(url, unicode):
+        if PY2 and isinstance(url, unicode):
             url = url.encode(self.encoding)
         schema, netloc, path, query, fragment = urlsplit(url)
         query = parse_qs(query)
         # sort for testing predictability
-        for key, val in sorted(newparams.iteritems()):
+        for key, val in sorted(newparams.items()):
             query[key] = (self.url_quote(val),)
         query = '&'.join(u'%s=%s' % (param, value)
                          for param, values in sorted(query.items())
--- a/rqlrewrite.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/rqlrewrite.py	Thu Dec 10 12:34:15 2015 +0100
@@ -22,6 +22,8 @@
 """
 __docformat__ = "restructuredtext en"
 
+from six import text_type, string_types
+
 from rql import nodes as n, stmts, TypeResolverException
 from rql.utils import common_parent
 
@@ -54,7 +56,7 @@
     eschema = schema.eschema
     allpossibletypes = {}
     for solution in solutions:
-        for varname, etype in solution.iteritems():
+        for varname, etype in solution.items():
             # XXX not considering aliases by design, right ?
             if varname not in newroot.defined_vars or eschema(etype).final:
                 continue
@@ -92,7 +94,7 @@
                     for etype in sorted(possibletypes):
                         node.append(n.Constant(etype, 'etype'))
                 else:
-                    etype = iter(possibletypes).next()
+                    etype = next(iter(possibletypes))
                     node = n.Constant(etype, 'etype')
                 comp = mytyperel.children[1]
                 comp.replace(comp.children[0], node)
@@ -286,7 +288,7 @@
                         if fnode.name == 'FTIRANK':
                             # we've to fetch the has_text relation as well
                             var = fnode.children[0].variable
-                            rel = iter(var.stinfo['ftirels']).next()
+                            rel = next(iter(var.stinfo['ftirels']))
                             assert not rel.ored(), 'unsupported'
                             newselect.add_restriction(rel.copy(newselect))
                             # remove relation from the orig select and
@@ -330,7 +332,7 @@
             union.replace(select, newselect)
         elif not () in localchecks:
             union.remove(select)
-        for lcheckdef, lchecksolutions in localchecks.iteritems():
+        for lcheckdef, lchecksolutions in localchecks.items():
             if not lcheckdef:
                 continue
             myrqlst = select.copy(solutions=lchecksolutions)
@@ -427,7 +429,7 @@
     def insert_varmap_snippets(self, varmap, rqlexprs, varexistsmap):
         try:
             self.init_from_varmap(varmap, varexistsmap)
-        except VariableFromSubQuery, ex:
+        except VariableFromSubQuery as ex:
             # variable may have been moved to a newly inserted subquery
             # we should insert snippet in that subquery
             subquery = self.select.aliases[ex.variable].query
@@ -548,7 +550,7 @@
                     'cant check security of %s, ambigous type for %s in %s',
                     stmt, varname, key[0]) # key[0] == the rql expression
                 raise Unauthorized()
-            etype = iter(ptypes).next()
+            etype = next(iter(ptypes))
             eschema = self.schema.eschema(etype)
             if not eschema.has_perm(self.session, action):
                 rqlexprs = eschema.get_rqlexprs(action)
@@ -621,7 +623,7 @@
             while argname in self.kwargs:
                 argname = subselect.allocate_varname()
             subselect.add_constant_restriction(subselect.get_variable(self.u_varname),
-                                               'eid', unicode(argname), 'Substitute')
+                                               'eid', text_type(argname), 'Substitute')
             self.kwargs[argname] = self.session.user.eid
         add_types_restriction(self.schema, subselect, subselect,
                               solutions=self.solutions)
@@ -646,7 +648,7 @@
         # insert "is" where necessary
         varexistsmap = {}
         self.removing_ambiguity = True
-        for (erqlexpr, varmap, oldvarname), etype in variantes[0].iteritems():
+        for (erqlexpr, varmap, oldvarname), etype in variantes[0].items():
             varname = self.rewritten[(erqlexpr, varmap, oldvarname)]
             var = self.select.defined_vars[varname]
             exists = var.references()[0].scope
@@ -655,7 +657,7 @@
         # insert ORED exists where necessary
         for variante in variantes[1:]:
             self.insert_snippets(snippets, varexistsmap)
-            for key, etype in variante.iteritems():
+            for key, etype in variante.items():
                 varname = self.rewritten[key]
                 try:
                     var = self.select.defined_vars[varname]
@@ -674,7 +676,7 @@
         variantes = set()
         for sol in newsolutions:
             variante = []
-            for key, newvar in self.rewritten.iteritems():
+            for key, newvar in self.rewritten.items():
                 variante.append( (key, sol[newvar]) )
             variantes.add(tuple(variante))
         # rebuild variantes as dict
@@ -682,7 +684,7 @@
         # remove variable which have always the same type
         for key in self.rewritten:
             it = iter(variantes)
-            etype = it.next()[key]
+            etype = next(it)[key]
             for variante in it:
                 if variante[key] != etype:
                     break
@@ -700,7 +702,7 @@
                 # no more references, undefine the variable
                 del self.select.defined_vars[vref.name]
                 removed.add(vref.name)
-        for key, newvar in self.rewritten.items(): # I mean items we alter it
+        for key, newvar in list(self.rewritten.items()):
             if newvar in removed:
                 del self.rewritten[key]
 
@@ -760,7 +762,7 @@
                 # insert "U eid %(u)s"
                 stmt.add_constant_restriction(
                     stmt.get_variable(self.u_varname),
-                    'eid', unicode(argname), 'Substitute')
+                    'eid', text_type(argname), 'Substitute')
                 self.kwargs[argname] = self.session.user.eid
             return self.u_varname
         key = (self.current_expr, self.varmap, vname)
@@ -883,7 +885,7 @@
                 return n.Constant(vi['const'], 'Int')
             return n.VariableRef(stmt.get_variable(selectvar))
         vname_or_term = self._get_varname_or_term(node.name)
-        if isinstance(vname_or_term, basestring):
+        if isinstance(vname_or_term, string_types):
             return n.VariableRef(stmt.get_variable(vname_or_term))
         # shared term
         return vname_or_term.copy(stmt)
--- a/rset.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/rset.py	Thu Dec 10 12:34:15 2015 +0100
@@ -16,11 +16,13 @@
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """The `ResultSet` class which is returned as result of an rql query"""
-
 __docformat__ = "restructuredtext en"
 
 from warnings import warn
 
+from six import PY3
+from six.moves import range
+
 from logilab.common import nullobject
 from logilab.common.decorators import cached, clear_cache, copy_cache
 from rql import nodes, stmts
@@ -101,7 +103,7 @@
         if self._rsetactions is None:
             self._rsetactions = {}
         if kwargs:
-            key = tuple(sorted(kwargs.iteritems()))
+            key = tuple(sorted(kwargs.items()))
         else:
             key = None
         try:
@@ -120,10 +122,6 @@
         """returns the ith element of the result set"""
         return self.rows[i] #ResultSetRow(self.rows[i])
 
-    def __getslice__(self, i, j):
-        """returns slice [i:j] of the result set"""
-        return self.rows[i:j]
-
     def __iter__(self):
         """Returns an iterator over rows"""
         return iter(self.rows)
@@ -186,7 +184,7 @@
         """
         rows, descr = [], []
         rset = self.copy(rows, descr)
-        for i in xrange(len(self)):
+        for i in range(len(self)):
             if not filtercb(self.get_entity(i, col)):
                 continue
             rows.append(self.rows[i])
@@ -215,10 +213,10 @@
         rset = self.copy(rows, descr)
         if col >= 0:
             entities = sorted(enumerate(self.entities(col)),
-                              key=lambda (i, e): keyfunc(e), reverse=reverse)
+                              key=lambda t: keyfunc(t[1]), reverse=reverse)
         else:
             entities = sorted(enumerate(self),
-                              key=lambda (i, e): keyfunc(e), reverse=reverse)
+                              key=lambda t: keyfunc(t[1]), reverse=reverse)
         for index, _ in entities:
             rows.append(self.rows[index])
             descr.append(self.description[index])
@@ -311,7 +309,7 @@
             newselect.limit = limit
             newselect.offset = offset
             aliases = [nodes.VariableRef(newselect.get_variable(chr(65+i), i))
-                       for i in xrange(len(rqlst.children[0].selection))]
+                       for i in range(len(rqlst.children[0].selection))]
             for vref in aliases:
                 newselect.append_selected(nodes.VariableRef(vref.variable))
             newselect.set_with([nodes.SubQuery(aliases, rqlst)], check=False)
@@ -322,7 +320,7 @@
         return rql
 
     def limit(self, limit, offset=0, inplace=False):
-        """limit the result set to the given number of rows optionaly starting
+        """limit the result set to the given number of rows optionally starting
         from an index different than 0
 
         :type limit: int
@@ -373,6 +371,8 @@
             warn('[3.21] the "encoded" argument is deprecated', DeprecationWarning)
         encoding = self.req.encoding
         rqlstr = self.syntax_tree().as_string(kwargs=self.args)
+        if PY3:
+            return rqlstr
         # sounds like we get encoded or unicode string due to a bug in as_string
         if not encoded:
             if isinstance(rqlstr, unicode):
@@ -387,7 +387,7 @@
 
     def entities(self, col=0):
         """iter on entities with eid in the `col` column of the result set"""
-        for i in xrange(len(self)):
+        for i in range(len(self)):
             # may have None values in case of outer join (or aggregat on eid
             # hacks)
             if self.rows[i][col] is not None:
@@ -507,9 +507,9 @@
             eschema = entity.e_schema
             eid_col, attr_cols, rel_cols = self._rset_structure(eschema, col)
             entity.eid = rowvalues[eid_col]
-            for attr, col_idx in attr_cols.iteritems():
+            for attr, col_idx in attr_cols.items():
                 entity.cw_attr_cache[attr] = rowvalues[col_idx]
-            for (rtype, role), col_idx in rel_cols.iteritems():
+            for (rtype, role), col_idx in rel_cols.items():
                 value = rowvalues[col_idx]
                 if value is None:
                     if role == 'subject':
@@ -606,7 +606,7 @@
                 except AttributeError:
                     # not a variable
                     continue
-                for i in xrange(len(select.selection)):
+                for i in range(len(select.selection)):
                     if i == col:
                         continue
                     coletype = self.description[row][i]
--- a/rtags.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/rtags.py	Thu Dec 10 12:34:15 2015 +0100
@@ -40,6 +40,8 @@
 import logging
 from warnings import warn
 
+from six import string_types
+
 from logilab.common.logging_ext import set_log_methods
 from logilab.common.registry import RegistrableInstance, yes
 
@@ -95,7 +97,7 @@
     def init(self, schema, check=True):
         # XXX check existing keys against schema
         if check:
-            for (stype, rtype, otype, tagged), value in self._tagdefs.items():
+            for (stype, rtype, otype, tagged), value in list(self._tagdefs.items()):
                 for ertype in (stype, rtype, otype):
                     if ertype != '*' and not ertype in schema:
                         self.warning('removing rtag %s: %s, %s undefined in schema',
@@ -145,7 +147,7 @@
         return tag
 
     def _tag_etype_attr(self, etype, attr, desttype='*', *args, **kwargs):
-        if isinstance(attr, basestring):
+        if isinstance(attr, string_types):
             attr, role = attr, 'subject'
         else:
             attr, role = attr
--- a/schema.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/schema.py	Thu Dec 10 12:34:15 2015 +0100
@@ -16,15 +16,18 @@
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """classes to define schemas for CubicWeb"""
+from __future__ import print_function
 
 __docformat__ = "restructuredtext en"
-_ = unicode
 
 import re
 from os.path import join, basename
 from logging import getLogger
 from warnings import warn
 
+from six import PY2, text_type, string_types, add_metaclass
+from six.moves import range
+
 from logilab.common import tempattr
 from logilab.common.decorators import cached, clear_cache, monkeypatch, cachedproperty
 from logilab.common.logging_ext import set_log_methods
@@ -45,7 +48,7 @@
 from rql.analyze import ETypeResolver
 
 import cubicweb
-from cubicweb import ETYPE_NAME_MAP, ValidationError, Unauthorized
+from cubicweb import ETYPE_NAME_MAP, ValidationError, Unauthorized, _
 
 try:
     from cubicweb import server
@@ -102,6 +105,9 @@
 INTERNAL_TYPES = set(('CWProperty', 'CWCache', 'ExternalUri', 'CWDataImport',
                       'CWSource', 'CWSourceHostConfig', 'CWSourceSchemaConfig'))
 
+UNIQUE_CONSTRAINTS = ('SizeConstraint', 'FormatConstraint',
+                      'StaticVocabularyConstraint',
+                      'RQLVocabularyConstraint')
 
 _LOGGER = getLogger('cubicweb.schemaloader')
 
@@ -142,7 +148,10 @@
     suppressing and reinserting an expression if only a space has been
     added/removed for instance)
     """
-    return u', '.join(' '.join(expr.split()) for expr in rqlstring.split(','))
+    union = parse(u'Any 1 WHERE %s' % rqlstring).as_string()
+    if PY2 and isinstance(union, str):
+        union = union.decode('utf-8')
+    return union.split(' WHERE ', 1)[1]
 
 
 def _check_valid_formula(rdef, formula_rqlst):
@@ -204,7 +213,7 @@
         """
         self.eid = eid # eid of the entity representing this rql expression
         assert mainvars, 'bad mainvars %s' % mainvars
-        if isinstance(mainvars, basestring):
+        if isinstance(mainvars, string_types):
             mainvars = set(splitstrip(mainvars))
         elif not isinstance(mainvars, set):
             mainvars = set(mainvars)
@@ -246,6 +255,9 @@
             return self.expression == other.expression
         return False
 
+    def __ne__(self, other):
+        return not (self == other)
+
     def __hash__(self):
         return hash(self.expression)
 
@@ -271,7 +283,7 @@
     def transform_has_permission(self):
         found = None
         rqlst = self.rqlst
-        for var in rqlst.defined_vars.itervalues():
+        for var in rqlst.defined_vars.values():
             for varref in var.references():
                 rel = varref.relation()
                 if rel is None:
@@ -319,7 +331,7 @@
         """
         creating = kwargs.get('creating')
         if not creating and self.eid is not None:
-            key = (self.eid, tuple(sorted(kwargs.iteritems())))
+            key = (self.eid, tuple(sorted(kwargs.items())))
             try:
                 return _cw.local_perm_cache[key]
             except KeyError:
@@ -363,7 +375,7 @@
             get_eschema = _cw.vreg.schema.eschema
             try:
                 for eaction, col in has_perm_defs:
-                    for i in xrange(len(rset)):
+                    for i in range(len(rset)):
                         eschema = get_eschema(rset.description[i][col])
                         eschema.check_perm(_cw, eaction, eid=rset[i][col])
                 if self.eid is not None:
@@ -400,13 +412,35 @@
             return self._check(_cw, x=eid, **kwargs)
         return self._check(_cw, **kwargs)
 
-def constraint_by_eid(self, eid):
-    for cstr in self.constraints:
-        if cstr.eid == eid:
-            return cstr
-    raise ValueError('No constraint with eid %d' % eid)
-RelationDefinitionSchema.constraint_by_eid = constraint_by_eid
+
+class CubicWebRelationDefinitionSchema(RelationDefinitionSchema):
+    def constraint_by_eid(self, eid):
+        for cstr in self.constraints:
+            if cstr.eid == eid:
+                return cstr
+        raise ValueError('No constraint with eid %d' % eid)
+
+    def rql_expression(self, expression, mainvars=None, eid=None):
+        """rql expression factory"""
+        if self.rtype.final:
+            return ERQLExpression(expression, mainvars, eid)
+        return RRQLExpression(expression, mainvars, eid)
 
+    def check_permission_definitions(self):
+        super(CubicWebRelationDefinitionSchema, self).check_permission_definitions()
+        schema = self.subject.schema
+        for action, groups in self.permissions.items():
+            for group_or_rqlexpr in groups:
+                if action == 'read' and \
+                       isinstance(group_or_rqlexpr, RQLExpression):
+                    msg = "can't use rql expression for read permission of %s"
+                    raise BadSchemaDefinition(msg % self)
+                if self.final and isinstance(group_or_rqlexpr, RRQLExpression):
+                    msg = "can't use RRQLExpression on %s, use an ERQLExpression"
+                    raise BadSchemaDefinition(msg % self)
+                if not self.final and isinstance(group_or_rqlexpr, ERQLExpression):
+                    msg = "can't use ERQLExpression on %s, use a RRQLExpression"
+                    raise BadSchemaDefinition(msg % self)
 
 def vargraph(rqlst):
     """ builds an adjacency graph of variables from the rql syntax tree, e.g:
@@ -522,7 +556,7 @@
             if not deps:
                 eschemas.append(eschema)
                 del graph[eschema]
-                for deps in graph.itervalues():
+                for deps in graph.values():
                     try:
                         deps.remove(eschema)
                     except KeyError:
@@ -548,9 +582,9 @@
         key = key + '_' + form
     # ensure unicode
     if context is not None:
-        return unicode(req.pgettext(context, key))
+        return text_type(req.pgettext(context, key))
     else:
-        return unicode(req._(key))
+        return text_type(req._(key))
 
 
 # Schema objects definition ###################################################
@@ -576,7 +610,7 @@
     assert action in self.ACTIONS, action
     #assert action in self._groups, '%s %s' % (self, action)
     try:
-        return frozenset(g for g in self.permissions[action] if isinstance(g, basestring))
+        return frozenset(g for g in self.permissions[action] if isinstance(g, string_types))
     except KeyError:
         return ()
 PermissionMixIn.get_groups = get_groups
@@ -595,7 +629,7 @@
     assert action in self.ACTIONS, action
     #assert action in self._rqlexprs, '%s %s' % (self, action)
     try:
-        return tuple(g for g in self.permissions[action] if not isinstance(g, basestring))
+        return tuple(g for g in self.permissions[action] if not isinstance(g, string_types))
     except KeyError:
         return ()
 PermissionMixIn.get_rqlexprs = get_rqlexprs
@@ -665,7 +699,7 @@
     groups = self.get_groups(action)
     if _cw.user.matching_groups(groups):
         if DBG:
-            print ('check_perm: %r %r: user matches %s' % (action, _self_str, groups))
+            print('check_perm: %r %r: user matches %s' % (action, _self_str, groups))
         return
     # if 'owners' in allowed groups, check if the user actually owns this
     # object, if so that's enough
@@ -676,14 +710,14 @@
           kwargs.get('creating')
           or ('eid' in kwargs and _cw.user.owns(kwargs['eid']))):
         if DBG:
-            print ('check_perm: %r %r: user is owner or creation time' %
-                   (action, _self_str))
+            print('check_perm: %r %r: user is owner or creation time' %
+                  (action, _self_str))
         return
     # else if there is some rql expressions, check them
     if DBG:
-        print ('check_perm: %r %r %s' %
-               (action, _self_str, [(rqlexpr, kwargs, rqlexpr.check(_cw, **kwargs))
-                                    for rqlexpr in self.get_rqlexprs(action)]))
+        print('check_perm: %r %r %s' %
+              (action, _self_str, [(rqlexpr, kwargs, rqlexpr.check(_cw, **kwargs))
+                                   for rqlexpr in self.get_rqlexprs(action)]))
     if any(rqlexpr.check(_cw, **kwargs)
            for rqlexpr in self.get_rqlexprs(action)):
         return
@@ -691,35 +725,10 @@
 PermissionMixIn.check_perm = check_perm
 
 
-RelationDefinitionSchema._RPROPERTIES['eid'] = None
+CubicWebRelationDefinitionSchema._RPROPERTIES['eid'] = None
 # remember rproperties defined at this point. Others will have to be serialized in
 # CWAttribute.extra_props
-KNOWN_RPROPERTIES = RelationDefinitionSchema.ALL_PROPERTIES()
-
-def rql_expression(self, expression, mainvars=None, eid=None):
-    """rql expression factory"""
-    if self.rtype.final:
-        return ERQLExpression(expression, mainvars, eid)
-    return RRQLExpression(expression, mainvars, eid)
-RelationDefinitionSchema.rql_expression = rql_expression
-
-orig_check_permission_definitions = RelationDefinitionSchema.check_permission_definitions
-def check_permission_definitions(self):
-    orig_check_permission_definitions(self)
-    schema = self.subject.schema
-    for action, groups in self.permissions.iteritems():
-        for group_or_rqlexpr in groups:
-            if action == 'read' and \
-                   isinstance(group_or_rqlexpr, RQLExpression):
-                msg = "can't use rql expression for read permission of %s"
-                raise BadSchemaDefinition(msg % self)
-            if self.final and isinstance(group_or_rqlexpr, RRQLExpression):
-                msg = "can't use RRQLExpression on %s, use an ERQLExpression"
-                raise BadSchemaDefinition(msg % self)
-            if not self.final and isinstance(group_or_rqlexpr, ERQLExpression):
-                msg = "can't use ERQLExpression on %s, use a RRQLExpression"
-                raise BadSchemaDefinition(msg % self)
-RelationDefinitionSchema.check_permission_definitions = check_permission_definitions
+KNOWN_RPROPERTIES = CubicWebRelationDefinitionSchema.ALL_PROPERTIES()
 
 
 class CubicWebEntitySchema(EntitySchema):
@@ -763,7 +772,7 @@
 
     def check_permission_definitions(self):
         super(CubicWebEntitySchema, self).check_permission_definitions()
-        for groups in self.permissions.itervalues():
+        for groups in self.permissions.values():
             for group_or_rqlexpr in groups:
                 if isinstance(group_or_rqlexpr, RRQLExpression):
                     msg = "can't use RRQLExpression on %s, use an ERQLExpression"
@@ -870,6 +879,7 @@
 class CubicWebRelationSchema(PermissionMixIn, RelationSchema):
     permissions = {}
     ACTIONS = ()
+    rdef_class = CubicWebRelationDefinitionSchema
 
     def __init__(self, schema=None, rdef=None, eid=None, **kwargs):
         if rdef is not None:
@@ -906,7 +916,7 @@
                 if rdef.may_have_permission(action, req):
                     return True
         else:
-            for rdef in self.rdefs.itervalues():
+            for rdef in self.rdefs.values():
                 if rdef.may_have_permission(action, req):
                     return True
         return False
@@ -948,7 +958,7 @@
                 if not rdef.has_perm(_cw, action, **kwargs):
                     return False
         else:
-            for rdef in self.rdefs.itervalues():
+            for rdef in self.rdefs.values():
                 if not rdef.has_perm(_cw, action, **kwargs):
                     return False
         return True
@@ -986,7 +996,7 @@
 
     etype_name_re = r'[A-Z][A-Za-z0-9]*[a-z]+[A-Za-z0-9]*$'
     def add_entity_type(self, edef):
-        edef.name = edef.name.encode()
+        edef.name = str(edef.name)
         edef.name = bw_normalize_etype(edef.name)
         if not re.match(self.etype_name_re, edef.name):
             raise BadSchemaDefinition(
@@ -1011,7 +1021,7 @@
             raise BadSchemaDefinition(
                 '%r is not a valid name for a relation type. It should be '
                 'lower cased' % rdef.name)
-        rdef.name = rdef.name.encode()
+        rdef.name = str(rdef.name)
         rschema = super(CubicWebSchema, self).add_relation_type(rdef)
         self._eid_index[rschema.eid] = rschema
         return rschema
@@ -1071,7 +1081,7 @@
 
     def iter_computed_attributes(self):
         for relation in self.relations():
-            for rdef in relation.rdefs.itervalues():
+            for rdef in relation.rdefs.values():
                 if rdef.final and rdef.formula is not None:
                     yield rdef
 
@@ -1198,11 +1208,11 @@
         return ';%s;%s\n%s' % (','.join(sorted(self.mainvars)), self.expression,
                                self.msg or '')
 
+    @classmethod
     def deserialize(cls, value):
         value, msg = value.split('\n', 1)
         _, mainvars, expression = value.split(';', 2)
         return cls(expression, mainvars, msg)
-    deserialize = classmethod(deserialize)
 
     def repo_check(self, session, eidfrom, rtype, eidto=None):
         """raise ValidationError if the relation doesn't satisfy the constraint
@@ -1245,7 +1255,7 @@
         return _cw.execute(rql, args, build_descr=False)
 
 
-class RQLConstraint(RepoEnforcedRQLConstraintMixIn, RQLVocabularyConstraint):
+class RQLConstraint(RepoEnforcedRQLConstraintMixIn, BaseRQLConstraint):
     """the rql constraint is similar to the RQLVocabularyConstraint but
     are also enforced at the repository level
     """
@@ -1287,12 +1297,13 @@
             make_workflowable(cls)
         return cls
 
+
+@add_metaclass(workflowable_definition)
 class WorkflowableEntityType(ybo.EntityType):
     """Use this base class instead of :class:`EntityType` to have workflow
     relations (i.e. `in_state`, `wf_info_for` and `custom_workflow`) on your
     entity type.
     """
-    __metaclass__ = workflowable_definition
     __abstract__ = True
 
 
--- a/schemas/Bookmark.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/schemas/Bookmark.py	Thu Dec 10 12:34:15 2015 +0100
@@ -19,7 +19,7 @@
 
 """
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from yams.buildobjs import EntityType, RelationType, SubjectRelation, String
 from cubicweb.schema import RRQLExpression
--- a/schemas/base.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/schemas/base.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,7 +18,7 @@
 """core CubicWeb schema, but not necessary at bootstrap time"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from yams.buildobjs import (EntityType, RelationType, RelationDefinition,
                             SubjectRelation,
@@ -379,5 +379,3 @@
         'add':    ('managers', RRQLExpression('U has_update_permission S'),),
         'delete': ('managers', RRQLExpression('U has_update_permission S'),),
         }
-
-
--- a/schemas/bootstrap.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/schemas/bootstrap.py	Thu Dec 10 12:34:15 2015 +0100
@@ -19,7 +19,7 @@
 """
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from yams.buildobjs import (EntityType, RelationType, RelationDefinition, Bytes,
                             SubjectRelation, RichString, String, Boolean, Int)
--- a/schemas/workflow.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/schemas/workflow.py	Thu Dec 10 12:34:15 2015 +0100
@@ -19,7 +19,7 @@
 
 """
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from yams.buildobjs import (EntityType, RelationType, RelationDefinition,
                             SubjectRelation,
@@ -273,7 +273,7 @@
     """indicate the current state of an entity"""
     __permissions__ = RO_REL_PERMS
 
-    # not inlined intentionnaly since when using ldap sources, user'state
+    # not inlined intentionnally since when using ldap sources, user'state
     # has to be stored outside the CWUser table
     inlined = False
 
--- a/selectors.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/selectors.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,6 +18,8 @@
 
 from warnings import warn
 
+from six import string_types
+
 from logilab.common.deprecation import deprecated, class_renamed
 
 from cubicweb.predicates import *
@@ -84,7 +86,7 @@
 
     See `EntityPredicate` documentation for behaviour when row is not specified.
 
-    :param *etypes: entity types (`basestring`) which should be refused
+    :param *etypes: entity types (`string_types`) which should be refused
     """
     def __init__(self, *etypes):
         super(_but_etype, self).__init__()
--- a/server/__init__.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/__init__.py	Thu Dec 10 12:34:15 2015 +0100
@@ -20,6 +20,7 @@
 
 The server module contains functions to initialize a new repository.
 """
+from __future__ import print_function
 
 __docformat__ = "restructuredtext en"
 
@@ -28,6 +29,9 @@
 from glob import glob
 from contextlib import contextmanager
 
+from six import text_type, string_types
+from six.moves import filter
+
 from logilab.common.modutils import LazyObject
 from logilab.common.textutils import splitstrip
 from logilab.common.registry import yes
@@ -138,7 +142,7 @@
     if not debugmode:
         DEBUG = 0
         return
-    if isinstance(debugmode, basestring):
+    if isinstance(debugmode, string_types):
         for mode in splitstrip(debugmode, sep='|'):
             DEBUG |= globals()[mode]
     else:
@@ -196,7 +200,7 @@
     user = session.create_entity('CWUser', login=login, upassword=pwd)
     for group in groups:
         session.execute('SET U in_group G WHERE U eid %(u)s, G name %(group)s',
-                        {'u': user.eid, 'group': unicode(group)})
+                        {'u': user.eid, 'group': text_type(group)})
     return user
 
 def init_repository(config, interactive=True, drop=False, vreg=None,
@@ -225,67 +229,72 @@
     sourcescfg = config.read_sources_file()
     source = sourcescfg['system']
     driver = source['db-driver']
-    sqlcnx = repo.system_source.get_connection()
-    sqlcursor = sqlcnx.cursor()
-    execute = sqlcursor.execute
-    if drop:
-        helper = database.get_db_helper(driver)
-        dropsql = sql_drop_all_user_tables(helper, sqlcursor)
-        # We may fail dropping some tables because of table dependencies, in a first pass.
-        # So, we try a second drop sequence to drop remaining tables if needed.
-        # Note that 2 passes is an arbitrary choice as it seems enougth for our usecases.
-        # (looping may induce infinite recursion when user have no right for example)
-        # Here we try to keep code simple and backend independant. That why we don't try to
-        # distinguish remaining tables (wrong right, dependencies, ...).
-        failed = sqlexec(dropsql, execute, cnx=sqlcnx,
-                         pbtitle='-> dropping tables (first pass)')
+    with repo.internal_cnx() as cnx:
+        sqlcnx = cnx.cnxset.cnx
+        sqlcursor = cnx.cnxset.cu
+        execute = sqlcursor.execute
+        if drop:
+            helper = database.get_db_helper(driver)
+            dropsql = sql_drop_all_user_tables(helper, sqlcursor)
+            # We may fail dropping some tables because of table dependencies, in a first pass.
+            # So, we try a second drop sequence to drop remaining tables if needed.
+            # Note that 2 passes is an arbitrary choice as it seems enough for our usecases
+            # (looping may induce infinite recursion when user have no rights for example).
+            # Here we try to keep code simple and backend independent. That's why we don't try to
+            # distinguish remaining tables (missing privileges, dependencies, ...).
+            failed = sqlexec(dropsql, execute, cnx=sqlcnx,
+                             pbtitle='-> dropping tables (first pass)')
+            if failed:
+                failed = sqlexec(failed, execute, cnx=sqlcnx,
+                                 pbtitle='-> dropping tables (second pass)')
+                remainings = list(filter(drop_filter, helper.list_tables(sqlcursor)))
+                assert not remainings, 'Remaining tables: %s' % ', '.join(remainings)
+        handler = config.migration_handler(schema, interactive=False, repo=repo, cnx=cnx)
+        # install additional driver specific sql files
+        handler.cmd_install_custom_sql_scripts()
+        for cube in reversed(config.cubes()):
+            handler.cmd_install_custom_sql_scripts(cube)
+        _title = '-> creating tables '
+        print(_title, end=' ')
+        # schema entities and relations tables
+        # can't skip entities table even if system source doesn't support them,
+        # they are used sometimes by generated sql. Keeping them empty is much
+        # simpler than fixing this...
+        schemasql = sqlschema(schema, driver)
+        #skip_entities=[str(e) for e in schema.entities()
+        #               if not repo.system_source.support_entity(str(e))])
+        failed = sqlexec(schemasql, execute, pbtitle=_title, delimiter=';;')
         if failed:
-            failed = sqlexec(failed, execute, cnx=sqlcnx,
-                             pbtitle='-> dropping tables (second pass)')
-            remainings = filter(drop_filter, helper.list_tables(sqlcursor))
-            assert not remainings, 'Remaining tables: %s' % ', '.join(remainings)
-    _title = '-> creating tables '
-    print _title,
-    # schema entities and relations tables
-    # can't skip entities table even if system source doesn't support them,
-    # they are used sometimes by generated sql. Keeping them empty is much
-    # simpler than fixing this...
-    schemasql = sqlschema(schema, driver)
-    #skip_entities=[str(e) for e in schema.entities()
-    #               if not repo.system_source.support_entity(str(e))])
-    failed = sqlexec(schemasql, execute, pbtitle=_title, delimiter=';;')
-    if failed:
-        print 'The following SQL statements failed. You should check your schema.'
-        print failed
-        raise Exception('execution of the sql schema failed, you should check your schema')
-    sqlcursor.close()
-    sqlcnx.commit()
-    sqlcnx.close()
+            print('The following SQL statements failed. You should check your schema.')
+            print(failed)
+            raise Exception('execution of the sql schema failed, you should check your schema')
+        sqlcursor.close()
+        sqlcnx.commit()
     with repo.internal_cnx() as cnx:
         # insert entity representing the system source
         ssource = cnx.create_entity('CWSource', type=u'native', name=u'system')
         repo.system_source.eid = ssource.eid
         cnx.execute('SET X cw_source X WHERE X eid %(x)s', {'x': ssource.eid})
         # insert base groups and default admin
-        print '-> inserting default user and default groups.'
+        print('-> inserting default user and default groups.')
         try:
-            login = unicode(sourcescfg['admin']['login'])
+            login = text_type(sourcescfg['admin']['login'])
             pwd = sourcescfg['admin']['password']
         except KeyError:
             if interactive:
                 msg = 'enter login and password of the initial manager account'
                 login, pwd = manager_userpasswd(msg=msg, confirm=True)
             else:
-                login, pwd = unicode(source['db-user']), source['db-password']
+                login, pwd = text_type(source['db-user']), source['db-password']
         # sort for eid predicatability as expected in some server tests
         for group in sorted(BASE_GROUPS):
-            cnx.create_entity('CWGroup', name=unicode(group))
+            cnx.create_entity('CWGroup', name=text_type(group))
         admin = create_user(cnx, login, pwd, u'managers')
         cnx.execute('SET X owned_by U WHERE X is IN (CWGroup,CWSource), U eid %(u)s',
                         {'u': admin.eid})
         cnx.commit()
     repo.shutdown()
-    # reloging using the admin user
+    # re-login using the admin user
     config._cubes = None # avoid assertion error
     repo = get_repository(config=config)
     with connect(repo, login, password=pwd) as cnx:
@@ -293,10 +302,6 @@
             repo.system_source.eid = ssource.eid # redo this manually
             handler = config.migration_handler(schema, interactive=False,
                                                cnx=cnx, repo=repo)
-            # install additional driver specific sql files
-            handler.cmd_install_custom_sql_scripts()
-            for cube in reversed(config.cubes()):
-                handler.cmd_install_custom_sql_scripts(cube)
             # serialize the schema
             initialize_schema(config, schema, handler)
             # yoo !
@@ -310,7 +315,7 @@
     # (drop instance attribute to get back to class attribute)
     del config.cubicweb_appobject_path
     del config.cube_appobject_path
-    print '-> database for instance %s initialized.' % config.appid
+    print('-> database for instance %s initialized.' % config.appid)
 
 
 def initialize_schema(config, schema, mhandler, event='create'):
--- a/server/checkintegrity.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/checkintegrity.py	Thu Dec 10 12:34:15 2015 +0100
@@ -20,6 +20,8 @@
 * integrity of a CubicWeb repository. Hum actually only the system database is
   checked.
 """
+from __future__ import print_function
+
 __docformat__ = "restructuredtext en"
 
 import sys
@@ -27,7 +29,7 @@
 
 from logilab.common.shellutils import ProgressBar
 
-from cubicweb.schema import PURE_VIRTUAL_RTYPES, VIRTUAL_RTYPES
+from cubicweb.schema import PURE_VIRTUAL_RTYPES, VIRTUAL_RTYPES, UNIQUE_CONSTRAINTS
 from cubicweb.server.sqlutils import SQL_PREFIX
 
 def notify_fixed(fix):
@@ -90,11 +92,11 @@
     dbhelper = repo.system_source.dbhelper
     cursor = cnx.cnxset.cu
     if not dbhelper.has_fti_table(cursor):
-        print 'no text index table'
+        print('no text index table')
         dbhelper.init_fti(cursor)
     repo.system_source.do_fti = True  # ensure full-text indexation is activated
     if etypes is None:
-        print 'Reindexing entities'
+        print('Reindexing entities')
         etypes = set()
         for eschema in schema.entities():
             if eschema.final:
@@ -107,8 +109,8 @@
         # clear fti table first
         cnx.system_sql('DELETE FROM %s' % dbhelper.fti_table)
     else:
-        print 'Reindexing entities of type %s' % \
-              ', '.join(sorted(str(e) for e in etypes))
+        print('Reindexing entities of type %s' % \
+              ', '.join(sorted(str(e) for e in etypes)))
         # clear fti table first. Use subquery for sql compatibility
         cnx.system_sql("DELETE FROM %s WHERE EXISTS(SELECT 1 FROM ENTITIES "
                        "WHERE eid=%s AND type IN (%s))" % (
@@ -122,8 +124,7 @@
     source = repo.system_source
     for eschema in etypes:
         etype_class = cnx.vreg['etypes'].etype_class(str(eschema))
-        for fti_rql in etype_class.cw_fti_index_rql_queries(cnx):
-            rset = cnx.execute(fti_rql)
+        for rset in etype_class.cw_fti_index_rql_limit(cnx):
             source.fti_index_entities(cnx, rset.entities())
             # clear entity cache to avoid high memory consumption on big tables
             cnx.drop_entity_cache()
@@ -135,10 +136,7 @@
 
 def check_schema(schema, cnx, eids, fix=1):
     """check serialized schema"""
-    print 'Checking serialized schema'
-    unique_constraints = ('SizeConstraint', 'FormatConstraint',
-                          'VocabularyConstraint',
-                          'RQLVocabularyConstraint')
+    print('Checking serialized schema')
     rql = ('Any COUNT(X),RN,SN,ON,CTN GROUPBY RN,SN,ON,CTN ORDERBY 1 '
            'WHERE X is CWConstraint, R constrained_by X, '
            'R relation_type RT, RT name RN, R from_entity ST, ST name SN, '
@@ -146,17 +144,17 @@
     for count, rn, sn, on, cstrname in cnx.execute(rql):
         if count == 1:
             continue
-        if cstrname in unique_constraints:
-            print "ERROR: got %s %r constraints on relation %s.%s.%s" % (
-                count, cstrname, sn, rn, on)
+        if cstrname in UNIQUE_CONSTRAINTS:
+            print("ERROR: got %s %r constraints on relation %s.%s.%s" % (
+                count, cstrname, sn, rn, on))
             if fix:
-                print 'dunno how to fix, do it yourself'
+                print('dunno how to fix, do it yourself')
 
 
 
 def check_text_index(schema, cnx, eids, fix=1):
     """check all entities registered in the text index"""
-    print 'Checking text index'
+    print('Checking text index')
     msg = '  Entity with eid %s exists in the text index but in no source (autofix will remove from text index)'
     cursor = cnx.system_sql('SELECT uid FROM appears;')
     for row in cursor.fetchall():
@@ -170,7 +168,7 @@
 
 def check_entities(schema, cnx, eids, fix=1):
     """check all entities registered in the repo system table"""
-    print 'Checking entities system table'
+    print('Checking entities system table')
     # system table but no source
     msg = '  Entity %s with eid %s exists in the system table but in no source (autofix will delete the entity)'
     cursor = cnx.system_sql('SELECT eid,type FROM entities;')
@@ -228,7 +226,7 @@
                            'WHERE s.cw_name=e.type AND NOT EXISTS(SELECT 1 FROM is_instance_of_relation as cs '
                            '  WHERE cs.eid_from=e.eid AND cs.eid_to=s.cw_eid)')
         notify_fixed(True)
-    print 'Checking entities tables'
+    print('Checking entities tables')
     msg = '  Entity with eid %s exists in the %s table but not in the system table (autofix will delete the entity)'
     for eschema in schema.entities():
         if eschema.final:
@@ -263,7 +261,7 @@
     """check that eids referenced by relations are registered in the repo system
     table
     """
-    print 'Checking relations'
+    print('Checking relations')
     for rschema in schema.relations():
         if rschema.final or rschema.type in PURE_VIRTUAL_RTYPES:
             continue
@@ -287,7 +285,7 @@
             cursor = cnx.system_sql('SELECT eid_from FROM %s_relation;' % rschema)
         except Exception as ex:
             # usually because table doesn't exist
-            print 'ERROR', ex
+            print('ERROR', ex)
             continue
         for row in cursor.fetchall():
             eid = row[0]
@@ -310,14 +308,14 @@
 
 def check_mandatory_relations(schema, cnx, eids, fix=1):
     """check entities missing some mandatory relation"""
-    print 'Checking mandatory relations'
+    print('Checking mandatory relations')
     msg = '%s #%s is missing mandatory %s relation %s (autofix will delete the entity)'
     for rschema in schema.relations():
         if rschema.final or rschema in PURE_VIRTUAL_RTYPES or rschema in ('is', 'is_instance_of'):
             continue
         smandatory = set()
         omandatory = set()
-        for rdef in rschema.rdefs.itervalues():
+        for rdef in rschema.rdefs.values():
             if rdef.cardinality[0] in '1+':
                 smandatory.add(rdef.subject)
             if rdef.cardinality[1] in '1+':
@@ -340,12 +338,12 @@
     """check for entities stored in the system source missing some mandatory
     attribute
     """
-    print 'Checking mandatory attributes'
+    print('Checking mandatory attributes')
     msg = '%s #%s is missing mandatory attribute %s (autofix will delete the entity)'
     for rschema in schema.relations():
         if not rschema.final or rschema in VIRTUAL_RTYPES:
             continue
-        for rdef in rschema.rdefs.itervalues():
+        for rdef in rschema.rdefs.values():
             if rdef.cardinality[0] in '1+':
                 rql = 'Any X WHERE X %s NULL, X is %s, X cw_source S, S name "system"' % (
                     rschema, rdef.subject)
@@ -361,7 +359,7 @@
 
     FIXME: rewrite using RQL queries ?
     """
-    print 'Checking metadata'
+    print('Checking metadata')
     cursor = cnx.system_sql("SELECT DISTINCT type FROM entities;")
     eidcolumn = SQL_PREFIX + 'eid'
     msg = '  %s with eid %s has no %s (autofix will set it to now)'
@@ -403,9 +401,9 @@
         if fix:
             cnx.commit()
         else:
-            print
+            print()
         if not fix:
-            print 'WARNING: Diagnostic run, nothing has been corrected'
+            print('WARNING: Diagnostic run, nothing has been corrected')
     if reindex:
         cnx.rollback()
         reindex_entities(repo.schema, cnx, withpb=withpb)
--- a/server/cwzmq.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/cwzmq.py	Thu Dec 10 12:34:15 2015 +0100
@@ -65,7 +65,7 @@
 
     def add_subscriber(self, address):
         subscriber = Subscriber(self.ioloop, address)
-        for topic, callback in self._topics.iteritems():
+        for topic, callback in self._topics.items():
             subscriber.subscribe(topic, callback)
         self._subscribers.append(subscriber)
 
--- a/server/edition.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/edition.py	Thu Dec 10 12:34:15 2015 +0100
@@ -38,7 +38,7 @@
 class EditedEntity(dict):
     """encapsulate entities attributes being written by an RQL query"""
     def __init__(self, entity, **kwargs):
-        dict.__init__(self, **kwargs)
+        super(EditedEntity, self).__init__(**kwargs)
         self.entity = entity
         self.skip_security = set()
         self.querier_pending_relations = {}
@@ -50,15 +50,18 @@
 
     def __lt__(self, other):
         # we don't want comparison by value inherited from dict
-        return id(self) < id(other)
+        raise NotImplementedError
 
     def __eq__(self, other):
-        return id(self) == id(other)
+        return self is other
+
+    def __ne__(self, other):
+        return not (self == other)
 
     def __setitem__(self, attr, value):
         assert attr != 'eid'
         # don't add attribute into skip_security if already in edited
-        # attributes, else we may accidentaly skip a desired security check
+        # attributes, else we may accidentally skip a desired security check
         if attr not in self:
             self.skip_security.add(attr)
         self.edited_attribute(attr, value)
@@ -83,7 +86,7 @@
     def setdefault(self, attr, default):
         assert attr != 'eid'
         # don't add attribute into skip_security if already in edited
-        # attributes, else we may accidentaly skip a desired security check
+        # attributes, else we may accidentally skip a desired security check
         if attr not in self:
             self[attr] = default
         return self[attr]
@@ -93,7 +96,7 @@
             setitem = self.__setitem__
         else:
             setitem = self.edited_attribute
-        for attr, value in values.iteritems():
+        for attr, value in values.items():
             setitem(attr, value)
 
     def edited_attribute(self, attr, value):
--- a/server/hook.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/hook.py	Thu Dec 10 12:34:15 2015 +0100
@@ -248,6 +248,8 @@
 .. autoclass:: cubicweb.server.hook.LateOperation
 .. autoclass:: cubicweb.server.hook.DataOperationMixIn
 """
+from __future__ import print_function
+
 __docformat__ = "restructuredtext en"
 
 from warnings import warn
@@ -331,7 +333,7 @@
                         with cnx.running_hooks_ops():
                             for hook in hooks:
                                 if debug:
-                                    print event, _kwargs, hook
+                                    print(event, _kwargs, hook)
                                 hook()
 
     def get_pruned_hooks(self, cnx, event, entities, eids_from_to, kwargs):
@@ -370,7 +372,7 @@
         pruned = set()
         cnx.pruned_hooks_cache[cache_key] = pruned
         if look_for_selector is not None:
-            for id, hooks in self.iteritems():
+            for id, hooks in self.items():
                 for hook in hooks:
                     enabled_cat, main_filter = hook.filterable_selectors()
                     if enabled_cat is not None:
@@ -382,14 +384,14 @@
                            (main_filter.frometypes is not None  or \
                             main_filter.toetypes is not None):
                             continue
-                        first_kwargs = _iter_kwargs(entities, eids_from_to, kwargs).next()
+                        first_kwargs = next(_iter_kwargs(entities, eids_from_to, kwargs))
                         if not main_filter(hook, cnx, **first_kwargs):
                             pruned.add(hook)
         return pruned
 
 
     def filtered_possible_objects(self, pruned, *args, **kwargs):
-        for appobjects in self.itervalues():
+        for appobjects in self.values():
             if pruned:
                 filtered_objects = [obj for obj in appobjects if obj not in pruned]
                 if not filtered_objects:
@@ -636,7 +638,7 @@
     # to set in concrete class (mandatory)
     subject_relations = None
     object_relations = None
-    # to set in concrete class (optionaly)
+    # to set in concrete class (optionally)
     skip_subject_relations = ()
     skip_object_relations = ()
 
@@ -713,7 +715,7 @@
 
       the transaction has been either rolled back either:
 
-       * intentionaly
+       * intentionally
        * a 'precommit' event failed, in which case all operations are rolled back
          once 'revertprecommit'' has been called
 
--- a/server/hooksmanager.py	Wed Dec 09 18:42:13 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of CubicWeb.
-#
-# CubicWeb 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 2.1 of the License, or (at your option)
-# any later version.
-#
-# CubicWeb 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 CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
-from logilab.common.deprecation import class_renamed, class_moved
-from cubicweb.server import hook
-
-SystemHook = class_renamed('SystemHook', hook.Hook)
-Hook = class_moved(hook.Hook)
--- a/server/migractions.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/migractions.py	Thu Dec 10 12:34:15 2015 +0100
@@ -26,6 +26,8 @@
 * add an entity
 * execute raw RQL queries
 """
+from __future__ import print_function
+
 __docformat__ = "restructuredtext en"
 
 import sys
@@ -40,6 +42,8 @@
 from warnings import warn
 from contextlib import contextmanager
 
+from six import PY2, text_type
+
 from logilab.common.deprecation import deprecated
 from logilab.common.decorators import cached, clear_cache
 
@@ -93,7 +97,7 @@
             self.repo = repo
             self.session = cnx.session
         elif connect:
-            self.repo_connect()
+            self.repo = config.repository()
             self.set_cnx()
         else:
             self.session = None
@@ -134,30 +138,24 @@
             try:
                 self.cnx = repoapi.connect(self.repo, login, password=pwd)
                 if not 'managers' in self.cnx.user.groups:
-                    print 'migration need an account in the managers group'
+                    print('migration need an account in the managers group')
                 else:
                     break
             except AuthenticationError:
-                print 'wrong user/password'
+                print('wrong user/password')
             except (KeyboardInterrupt, EOFError):
-                print 'aborting...'
+                print('aborting...')
                 sys.exit(0)
             try:
                 login, pwd = manager_userpasswd()
             except (KeyboardInterrupt, EOFError):
-                print 'aborting...'
+                print('aborting...')
                 sys.exit(0)
         self.session = self.repo._get_session(self.cnx.sessionid)
 
-
-    @cached
-    def repo_connect(self):
-        self.repo = repoapi.get_repository(config=self.config)
-        return self.repo
-
     def cube_upgraded(self, cube, version):
         self.cmd_set_property('system.version.%s' % cube.lower(),
-                              unicode(version))
+                              text_type(version))
         self.commit()
 
     def shutdown(self):
@@ -191,7 +189,7 @@
 
     def backup_database(self, backupfile=None, askconfirm=True, format='native'):
         config = self.config
-        repo = self.repo_connect()
+        repo = self.repo
         # paths
         timestamp = datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
         instbkdir = osp.join(config.appdatahome, 'backup')
@@ -202,13 +200,13 @@
         # check backup has to be done
         if osp.exists(backupfile) and not \
                 self.confirm('Backup file %s exists, overwrite it?' % backupfile):
-            print '-> no backup done.'
+            print('-> no backup done.')
             return
         elif askconfirm and not self.confirm('Backup %s database?' % config.appid):
-            print '-> no backup done.'
+            print('-> no backup done.')
             return
         open(backupfile,'w').close() # kinda lock
-        os.chmod(backupfile, 0600)
+        os.chmod(backupfile, 0o600)
         # backup
         source = repo.system_source
         tmpdir = tempfile.mkdtemp()
@@ -217,7 +215,7 @@
             try:
                 source.backup(osp.join(tmpdir, source.uri), self.confirm, format=format)
             except Exception as ex:
-                print '-> error trying to backup %s [%s]' % (source.uri, ex)
+                print('-> error trying to backup %s [%s]' % (source.uri, ex))
                 if not self.confirm('Continue anyway?', default='n'):
                     raise SystemExit(1)
                 else:
@@ -226,7 +224,7 @@
                 format_file.write('%s\n' % format)
             with open(osp.join(tmpdir, 'versions.txt'), 'w') as version_file:
                 versions = repo.get_versions()
-                for cube, version in versions.iteritems():
+                for cube, version in versions.items():
                     version_file.write('%s %s\n' % (cube, version))
             if not failed:
                 bkup = tarfile.open(backupfile, 'w|gz')
@@ -236,7 +234,7 @@
                 # call hooks
                 repo.hm.call_hooks('server_backup', repo=repo, timestamp=timestamp)
                 # done
-                print '-> backup file',  backupfile
+                print('-> backup file',  backupfile)
         finally:
             shutil.rmtree(tmpdir)
 
@@ -268,19 +266,19 @@
                 if written_format in ('portable', 'native'):
                     format = written_format
         self.config.init_cnxset_pool = False
-        repo = self.repo_connect()
+        repo = self.repo = self.config.repository()
         source = repo.system_source
         try:
             source.restore(osp.join(tmpdir, source.uri), self.confirm, drop, format)
         except Exception as exc:
-            print '-> error trying to restore %s [%s]' % (source.uri, exc)
+            print('-> error trying to restore %s [%s]' % (source.uri, exc))
             if not self.confirm('Continue anyway?', default='n'):
                 raise SystemExit(1)
         shutil.rmtree(tmpdir)
         # call hooks
         repo.init_cnxset_pool()
         repo.hm.call_hooks('server_restore', repo=repo, timestamp=backupfile)
-        print '-> database restored.'
+        print('-> database restored.')
 
     def commit(self):
         self.cnx.commit()
@@ -362,11 +360,11 @@
             directory = osp.join(self.config.cube_dir(cube), 'schema')
         sql_scripts = glob(osp.join(directory, '*.%s.sql' % driver))
         for fpath in sql_scripts:
-            print '-> installing', fpath
+            print('-> installing', fpath)
             failed = sqlexec(open(fpath).read(), self.cnx.system_sql, False,
                              delimiter=';;')
             if failed:
-                print '-> ERROR, skipping', fpath
+                print('-> ERROR, skipping', fpath)
 
     # schema synchronization internals ########################################
 
@@ -424,7 +422,7 @@
                                      {'x': expreid}, ask_confirm=False)
                 else:
                     newexprs.pop(expression)
-            for expression in newexprs.itervalues():
+            for expression in newexprs.values():
                 expr = expression.expression
                 if not confirm or self.confirm('Add %s expression for %s permission of %s?'
                                                % (expr, action, erschema)):
@@ -460,7 +458,10 @@
             assert reporschema.eid, reporschema
             self.rqlexecall(ss.updaterschema2rql(rschema, reporschema.eid),
                             ask_confirm=self.verbosity>=2)
-        if syncrdefs:
+        if rschema.rule:
+            if syncperms:
+                self._synchronize_permissions(rschema, reporschema.eid)
+        elif syncrdefs:
             for subj, obj in rschema.rdefs:
                 if (subj, obj) not in reporschema.rdefs:
                     continue
@@ -552,12 +553,12 @@
                 for name in cols:
                     rschema = repoeschema.subjrels.get(name)
                     if rschema is None:
-                        print 'dont add %s unique constraint on %s, missing %s' % (
-                            ','.join(cols), eschema, name)
+                        print('dont add %s unique constraint on %s, missing %s' % (
+                            ','.join(cols), eschema, name))
                         return False
                     if not (rschema.final or rschema.inlined):
-                        print 'dont add %s unique constraint on %s, %s is neither final nor inlined' % (
-                            ','.join(cols), eschema, name)
+                        print('dont add %s unique constraint on %s, %s is neither final nor inlined' % (
+                            ','.join(cols), eschema, name))
                         return False
                 return True
 
@@ -574,6 +575,7 @@
         against its current definition:
         * order and other properties
         * constraints
+        * permissions
         """
         subjtype, objtype = str(subjtype), str(objtype)
         rschema = self.fs_schema.rschema(rtype)
@@ -743,8 +745,8 @@
             rschema = self.repo.schema.rschema(attrname)
             attrtype = rschema.objects(etype)[0]
         except KeyError:
-            print 'warning: attribute %s %s is not known, skip deletion' % (
-                etype, attrname)
+            print('warning: attribute %s %s is not known, skip deletion' % (
+                etype, attrname))
         else:
             self.cmd_drop_relation_definition(etype, attrname, attrtype,
                                               commit=commit)
@@ -781,7 +783,7 @@
         instschema = self.repo.schema
         eschema = self.fs_schema.eschema(etype)
         if etype in instschema and not (eschema.final and eschema.eid is None):
-            print 'warning: %s already known, skip addition' % etype
+            print('warning: %s already known, skip addition' % etype)
             return
         confirm = self.verbosity >= 2
         groupmap = self.group_mapping()
@@ -899,9 +901,11 @@
             self.commit()
 
     def cmd_drop_entity_type(self, etype, commit=True):
-        """unregister an existing entity type
+        """Drop an existing entity type.
 
-        This will trigger deletion of necessary relation types and definitions
+        This will trigger deletion of necessary relation types and definitions.
+        Note that existing entities of the given type will be deleted without
+        any hooks called.
         """
         # XXX what if we delete an entity type which is specialized by other types
         # unregister the entity from CWEType
@@ -918,7 +922,7 @@
         """
         schema = self.repo.schema
         if oldname not in schema:
-            print 'warning: entity type %s is unknown, skip renaming' % oldname
+            print('warning: entity type %s is unknown, skip renaming' % oldname)
             return
         # if merging two existing entity types
         if newname in schema:
@@ -997,7 +1001,7 @@
         # elif simply renaming an entity type
         else:
             self.rqlexec('SET ET name %(newname)s WHERE ET is CWEType, ET name %(on)s',
-                         {'newname' : unicode(newname), 'on' : oldname},
+                         {'newname' : text_type(newname), 'on' : oldname},
                          ask_confirm=False)
         if commit:
             self.commit()
@@ -1017,8 +1021,8 @@
         rschema = self.fs_schema.rschema(rtype)
         execute = self.cnx.execute
         if rtype in reposchema:
-            print 'warning: relation type %s is already known, skip addition' % (
-                rtype)
+            print('warning: relation type %s is already known, skip addition' % (
+                rtype))
         elif rschema.rule:
             gmap = self.group_mapping()
             ss.execschemarql(execute, rschema, ss.crschema2rql(rschema, gmap))
@@ -1060,7 +1064,11 @@
             self.commit()
 
     def cmd_drop_relation_type(self, rtype, commit=True):
-        """unregister an existing relation type"""
+        """Drop an existing relation type.
+
+        Note that existing relations of the given type will be deleted without
+        any hooks called.
+        """
         self.rqlexec('DELETE CWRType X WHERE X name %r' % rtype,
                      ask_confirm=self.verbosity>=2)
         self.rqlexec('DELETE CWComputedRType X WHERE X name %r' % rtype,
@@ -1098,8 +1106,8 @@
         if not rtype in self.repo.schema:
             self.cmd_add_relation_type(rtype, addrdef=False, commit=True)
         if (subjtype, objtype) in self.repo.schema.rschema(rtype).rdefs:
-            print 'warning: relation %s %s %s is already known, skip addition' % (
-                subjtype, rtype, objtype)
+            print('warning: relation %s %s %s is already known, skip addition' % (
+                subjtype, rtype, objtype))
             return
         rdef = self._get_rdef(rschema, subjtype, objtype)
         ss.execschemarql(self.cnx.execute, rdef,
@@ -1120,7 +1128,11 @@
         return rdef
 
     def cmd_drop_relation_definition(self, subjtype, rtype, objtype, commit=True):
-        """unregister an existing relation definition"""
+        """Drop an existing relation definition.
+
+        Note that existing relations of the given definition will be deleted
+        without any hooks called.
+        """
         rschema = self.repo.schema.rschema(rtype)
         if rschema.rule:
             raise ExecutionError('Cannot drop a relation definition for a '
@@ -1200,7 +1212,7 @@
         values = []
         for k, v in kwargs.items():
             values.append('X %s %%(%s)s' % (k, k))
-            if isinstance(v, str):
+            if PY2 and isinstance(v, str):
                 kwargs[k] = unicode(v)
         rql = 'SET %s WHERE %s' % (','.join(values), ','.join(restriction))
         self.rqlexec(rql, kwargs, ask_confirm=self.verbosity>=2)
@@ -1233,7 +1245,7 @@
                 self.rqlexec('SET C value %%(v)s WHERE X from_entity S, X relation_type R,'
                              'X constrained_by C, C cstrtype CT, CT name "SizeConstraint",'
                              'S name "%s", R name "%s"' % (etype, rtype),
-                             {'v': unicode(SizeConstraint(size).serialize())},
+                             {'v': text_type(SizeConstraint(size).serialize())},
                              ask_confirm=self.verbosity>=2)
             else:
                 self.rqlexec('DELETE X constrained_by C WHERE X from_entity S, X relation_type R,'
@@ -1270,7 +1282,7 @@
 
          :rtype: `Workflow`
         """
-        wf = self.cmd_create_entity('Workflow', name=unicode(name),
+        wf = self.cmd_create_entity('Workflow', name=text_type(name),
                                     **kwargs)
         if not isinstance(wfof, (list, tuple)):
             wfof = (wfof,)
@@ -1278,19 +1290,19 @@
             return 'missing workflow relations, see make_workflowable(%s)' % etype
         for etype in wfof:
             eschema = self.repo.schema[etype]
-            etype = unicode(etype)
+            etype = text_type(etype)
             if ensure_workflowable:
                 assert 'in_state' in eschema.subjrels, _missing_wf_rel(etype)
                 assert 'custom_workflow' in eschema.subjrels, _missing_wf_rel(etype)
                 assert 'wf_info_for' in eschema.objrels, _missing_wf_rel(etype)
             rset = self.rqlexec(
                 'SET X workflow_of ET WHERE X eid %(x)s, ET name %(et)s',
-                {'x': wf.eid, 'et': unicode(etype)}, ask_confirm=False)
+                {'x': wf.eid, 'et': text_type(etype)}, ask_confirm=False)
             assert rset, 'unexistant entity type %s' % etype
             if default:
                 self.rqlexec(
                     'SET ET default_workflow X WHERE X eid %(x)s, ET name %(et)s',
-                    {'x': wf.eid, 'et': unicode(etype)}, ask_confirm=False)
+                    {'x': wf.eid, 'et': text_type(etype)}, ask_confirm=False)
         if commit:
             self.commit()
         return wf
@@ -1321,13 +1333,13 @@
         To set a user specific property value, use appropriate method on CWUser
         instance.
         """
-        value = unicode(value)
+        value = text_type(value)
         try:
             prop = self.rqlexec(
                 'CWProperty X WHERE X pkey %(k)s, NOT X for_user U',
-                {'k': unicode(pkey)}, ask_confirm=False).get_entity(0, 0)
+                {'k': text_type(pkey)}, ask_confirm=False).get_entity(0, 0)
         except Exception:
-            self.cmd_create_entity('CWProperty', pkey=unicode(pkey), value=value)
+            self.cmd_create_entity('CWProperty', pkey=text_type(pkey), value=value)
         else:
             prop.cw_set(value=value)
 
@@ -1351,7 +1363,7 @@
             # remove from entity cache to avoid memory exhaustion
             del entity.cw_attr_cache[attribute]
             pb.update()
-        print
+        print()
         source.set_storage(etype, attribute, storage)
 
     def cmd_create_entity(self, etype, commit=False, **kwargs):
@@ -1564,12 +1576,14 @@
             else:
                 raise StopIteration
 
-    def next(self):
+    def __next__(self):
         if self._rsetit is not None:
-            return self._rsetit.next()
+            return next(self._rsetit)
         rset = self._get_rset()
         self._rsetit = iter(rset)
-        return self._rsetit.next()
+        return next(self._rsetit)
+
+    next = __next__
 
     def entities(self):
         try:
--- a/server/querier.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/querier.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,10 +18,15 @@
 """Helper classes to execute RQL queries on a set of sources, performing
 security checking and data aggregation.
 """
+from __future__ import print_function
+
 __docformat__ = "restructuredtext en"
 
 from itertools import repeat
 
+from six import text_type, string_types, integer_types
+from six.moves import range
+
 from rql import RQLSyntaxError, CoercionError
 from rql.stmts import Union
 from rql.nodes import ETYPE_PYOBJ_MAP, etype_from_pyobj, Relation, Exists, Not
@@ -61,7 +66,7 @@
 def check_no_password_selected(rqlst):
     """check that Password entities are not selected"""
     for solution in rqlst.solutions:
-        for var, etype in solution.iteritems():
+        for var, etype in solution.items():
             if etype == 'Password':
                 raise Unauthorized('Password selection is not allowed (%s)' % var)
 
@@ -103,13 +108,13 @@
                                                    solution, args))
                 if not user.matching_groups(rdef.get_groups('read')):
                     if DBG:
-                        print ('check_read_access: %s %s does not match %s' %
-                               (rdef, user.groups, rdef.get_groups('read')))
+                        print('check_read_access: %s %s does not match %s' %
+                              (rdef, user.groups, rdef.get_groups('read')))
                     # XXX rqlexpr not allowed
                     raise Unauthorized('read', rel.r_type)
                 if DBG:
-                    print ('check_read_access: %s %s matches %s' %
-                           (rdef, user.groups, rdef.get_groups('read')))
+                    print('check_read_access: %s %s matches %s' %
+                          (rdef, user.groups, rdef.get_groups('read')))
 
 def get_local_checks(cnx, rqlst, solution):
     """Check that the given user has credentials to access data read by the
@@ -138,8 +143,8 @@
                 ex = Unauthorized('read', solution[varname])
                 ex.var = varname
                 if DBG:
-                    print ('check_read_access: %s %s %s %s' %
-                           (varname, eschema, user.groups, eschema.get_groups('read')))
+                    print('check_read_access: %s %s %s %s' %
+                          (varname, eschema, user.groups, eschema.get_groups('read')))
                 raise ex
             # don't insert security on variable only referenced by 'NOT X relation Y' or
             # 'NOT EXISTS(X relation Y)'
@@ -265,7 +270,7 @@
         # which have a known eid
         varkwargs = {}
         if not cnx.transaction_data.get('security-rqlst-cache'):
-            for var in rqlst.defined_vars.itervalues():
+            for var in rqlst.defined_vars.values():
                 if var.stinfo['constnode'] is not None:
                     eid = var.stinfo['constnode'].eval(self.args)
                     varkwargs[var.name] = int(eid)
@@ -285,7 +290,7 @@
                 newsolutions.append(solution)
                 # try to benefit of rqlexpr.check cache for entities which
                 # are specified by eid in query'args
-                for varname, eid in varkwargs.iteritems():
+                for varname, eid in varkwargs.items():
                     try:
                         rqlexprs = localcheck.pop(varname)
                     except KeyError:
@@ -303,7 +308,7 @@
                 # mark variables protected by an rql expression
                 restricted_vars.update(localcheck)
                 # turn local check into a dict key
-                localcheck = tuple(sorted(localcheck.iteritems()))
+                localcheck = tuple(sorted(localcheck.items()))
                 localchecks.setdefault(localcheck, []).append(solution)
         # raise Unautorized exception if the user can't access to any solution
         if not newsolutions:
@@ -334,7 +339,7 @@
 
     def __init__(self, querier, rqlst, args, cnx):
         ExecutionPlan.__init__(self, querier, rqlst, args, cnx)
-        # save originaly selected variable, we may modify this
+        # save originally selected variable, we may modify this
         # dictionary for substitution (query parameters)
         self.selected = rqlst.selection
         # list of rows of entities definition (ssplanner.EditedEntity)
@@ -414,7 +419,7 @@
 
     def relation_defs(self):
         """return the list for relation definitions to insert"""
-        for rdefs in self._expanded_r_defs.itervalues():
+        for rdefs in self._expanded_r_defs.values():
             for rdef in rdefs:
                 yield rdef
         for rdef in self.r_defs:
@@ -446,13 +451,13 @@
         relations = {}
         for subj, rtype, obj in self.relation_defs():
             # if a string is given into args instead of an int, we get it here
-            if isinstance(subj, basestring):
+            if isinstance(subj, string_types):
                 subj = int(subj)
-            elif not isinstance(subj, (int, long)):
+            elif not isinstance(subj, integer_types):
                 subj = subj.entity.eid
-            if isinstance(obj, basestring):
+            if isinstance(obj, string_types):
                 obj = int(obj)
-            elif not isinstance(obj, (int, long)):
+            elif not isinstance(obj, integer_types):
                 obj = obj.entity.eid
             if repo.schema.rschema(rtype).inlined:
                 if subj not in edited_entities:
@@ -468,7 +473,7 @@
                 else:
                     relations[rtype] = [(subj, obj)]
         repo.glob_add_relations(cnx, relations)
-        for edited in edited_entities.itervalues():
+        for edited in edited_entities.values():
             repo.glob_update_entity(cnx, edited)
 
 
@@ -507,7 +512,7 @@
     def parse(self, rql, annotate=False):
         """return a rql syntax tree for the given rql"""
         try:
-            return self._parse(unicode(rql), annotate=annotate)
+            return self._parse(text_type(rql), annotate=annotate)
         except UnicodeError:
             raise RQLSyntaxError(rql)
 
@@ -539,8 +544,8 @@
         """
         if server.DEBUG & (server.DBG_RQL | server.DBG_SQL):
             if server.DEBUG & (server.DBG_MORE | server.DBG_SQL):
-                print '*'*80
-            print 'querier input', repr(rql), repr(args)
+                print('*'*80)
+            print('querier input', repr(rql), repr(args))
         # parse the query and binds variables
         cachekey = (rql,)
         try:
@@ -601,7 +606,7 @@
             if args:
                 # different SQL generated when some argument is None or not (IS
                 # NULL). This should be considered when computing sql cache key
-                cachekey += tuple(sorted([k for k, v in args.iteritems()
+                cachekey += tuple(sorted([k for k, v in args.items()
                                           if v is None]))
         # make an execution plan
         plan = self.plan_factory(rqlst, args, cnx)
@@ -641,7 +646,7 @@
                 # so compute description manually even if there is only
                 # one solution
                 basedescr = [None] * len(plan.selected)
-                todetermine = zip(xrange(len(plan.selected)), repeat(False))
+                todetermine = list(zip(range(len(plan.selected)), repeat(False)))
                 descr = _build_descr(cnx, results, basedescr, todetermine)
             # FIXME: get number of affected entities / relations on non
             # selection queries ?
@@ -668,7 +673,7 @@
     unstables = rqlst.get_variable_indices()
     basedescr = []
     todetermine = []
-    for i in xrange(len(rqlst.children[0].selection)):
+    for i in range(len(rqlst.children[0].selection)):
         ttype = _selection_idx_type(i, rqlst, args)
         if ttype is None or ttype == 'Any':
             ttype = None
--- a/server/repository.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/repository.py	Thu Dec 10 12:34:15 2015 +0100
@@ -25,15 +25,18 @@
   point to a cubicweb instance.
 * handles session management
 """
+from __future__ import print_function
+
 __docformat__ = "restructuredtext en"
 
 import threading
-import Queue
 from warnings import warn
 from itertools import chain
 from time import time, localtime, strftime
 from contextlib import contextmanager
 
+from six.moves import range, queue
+
 from logilab.common.decorators import cached, clear_cache
 from logilab.common.deprecation import deprecated
 
@@ -186,18 +189,18 @@
         # registry hook to fix user class on registry reload
         @onevent('after-registry-reload', self)
         def fix_user_classes(self):
-            # After registery reload the 'CWUser' class used for CWEtype
-            # changed.  To any existing user object have a different class than
+            # After registry reload the 'CWUser' class used for CWEtype
+            # changed.  So any existing user object have a different class than
             # the new loaded one. We are hot fixing this.
             usercls = self.vreg['etypes'].etype_class('CWUser')
-            for session in self._sessions.itervalues():
+            for session in self._sessions.values():
                 if not isinstance(session.user, InternalManager):
                     session.user.__class__ = usercls
 
     def init_cnxset_pool(self):
         """should be called bootstrap_repository, as this is what it does"""
         config = self.config
-        self._cnxsets_pool = Queue.Queue()
+        self._cnxsets_pool = queue.Queue()
         # 0. init a cnxset that will be used to fetch bootstrap information from
         #    the database
         self._cnxsets_pool.put_nowait(self.system_source.wrapped_connection())
@@ -240,7 +243,7 @@
         #    proper initialization
         self._get_cnxset().close(True)
         self.cnxsets = [] # list of available cnxsets (can't iterate on a Queue)
-        for i in xrange(config['connections-pool-size']):
+        for i in range(config['connections-pool-size']):
             self.cnxsets.append(self.system_source.wrapped_connection())
             self._cnxsets_pool.put_nowait(self.cnxsets[-1])
 
@@ -308,7 +311,7 @@
         else:
             self.vreg._set_schema(schema)
         self.querier.set_schema(schema)
-        for source in self.sources_by_uri.itervalues():
+        for source in self.sources_by_uri.values():
             source.set_schema(schema)
         self.schema = schema
 
@@ -377,7 +380,7 @@
     def _get_cnxset(self):
         try:
             return self._cnxsets_pool.get(True, timeout=5)
-        except Queue.Empty:
+        except queue.Empty:
             raise Exception('no connections set available after 5 secs, probably either a '
                             'bug in code (too many uncommited/rolled back '
                             'connections) or too much load on the server (in '
@@ -387,13 +390,6 @@
     def _free_cnxset(self, cnxset):
         self._cnxsets_pool.put_nowait(cnxset)
 
-    def pinfo(self):
-        # XXX: session.cnxset is accessed from a local storage, would be interesting
-        #      to see if there is a cnxset set in any thread specific data)
-        return '%s: %s (%s)' % (self._cnxsets_pool.qsize(),
-                                ','.join(session.user.login for session in self._sessions.itervalues()
-                                         if session.cnxset),
-                                threading.currentThread())
     def shutdown(self):
         """called on server stop event to properly close opened sessions and
         connections
@@ -441,7 +437,7 @@
         """
         # iter on sources_by_uri then check enabled source since sources doesn't
         # contain copy based sources
-        for source in self.sources_by_uri.itervalues():
+        for source in self.sources_by_uri.values():
             if self.config.source_enabled(source) and source.support_entity('CWUser'):
                 try:
                     return source.authenticate(cnx, login, **authinfo)
@@ -575,7 +571,7 @@
         """
         sources = {}
         # remove sensitive information
-        for uri, source in self.sources_by_uri.iteritems():
+        for uri, source in self.sources_by_uri.items():
             sources[uri] = source.public_config
         return sources
 
@@ -623,7 +619,7 @@
                 raise Exception('bad input for find_user')
         with self.internal_cnx() as cnx:
             varmaker = rqlvar_maker()
-            vars = [(attr, varmaker.next()) for attr in fetch_attrs]
+            vars = [(attr, next(varmaker)) for attr in fetch_attrs]
             rql = 'Any %s WHERE X is CWUser, ' % ','.join(var[1] for var in vars)
             rql += ','.join('X %s %s' % (var[0], var[1]) for var in vars) + ','
             rset = cnx.execute(rql + ','.join('X %s %%(%s)s' % (attr, attr)
@@ -779,6 +775,7 @@
             args[key] = int(args[key])
         return tuple(cachekey)
 
+    @deprecated('[3.22] use the new store API')
     def extid2eid(self, source, extid, etype, cnx, insert=True,
                   sourceparams=None):
         """Return eid from a local id. If the eid is a negative integer, that
@@ -919,7 +916,7 @@
         # set caches asap
         extid = self.init_entity_caches(cnx, entity, source)
         if server.DEBUG & server.DBG_REPO:
-            print 'ADD entity', self, entity.cw_etype, entity.eid, edited
+            print('ADD entity', self, entity.cw_etype, entity.eid, edited)
         prefill_entity_caches(entity)
         self.hm.call_hooks('before_add_entity', cnx, entity=entity)
         relations = preprocess_inlined_relations(cnx, entity)
@@ -950,8 +947,8 @@
         """
         entity = edited.entity
         if server.DEBUG & server.DBG_REPO:
-            print 'UPDATE entity', entity.cw_etype, entity.eid, \
-                  entity.cw_attr_cache, edited
+            print('UPDATE entity', entity.cw_etype, entity.eid,
+                  entity.cw_attr_cache, edited)
         hm = self.hm
         eschema = entity.e_schema
         cnx.set_entity_cache(entity)
@@ -1043,9 +1040,9 @@
             except KeyError:
                 data_by_etype[etype] = [entity]
         source = self.system_source
-        for etype, entities in data_by_etype.iteritems():
+        for etype, entities in data_by_etype.items():
             if server.DEBUG & server.DBG_REPO:
-                print 'DELETE entities', etype, [entity.eid for entity in entities]
+                print('DELETE entities', etype, [entity.eid for entity in entities])
             self.hm.call_hooks('before_delete_entity', cnx, entities=entities)
             self._delete_cascade_multi(cnx, entities)
             source.delete_entities(cnx, entities)
@@ -1067,10 +1064,10 @@
         subjects_by_types = {}
         objects_by_types = {}
         activintegrity = cnx.is_hook_category_activated('activeintegrity')
-        for rtype, eids_subj_obj in relations.iteritems():
+        for rtype, eids_subj_obj in relations.items():
             if server.DEBUG & server.DBG_REPO:
                 for subjeid, objeid in eids_subj_obj:
-                    print 'ADD relation', subjeid, rtype, objeid
+                    print('ADD relation', subjeid, rtype, objeid)
             for subjeid, objeid in eids_subj_obj:
                 if rtype in relations_by_rtype:
                     relations_by_rtype[rtype].append((subjeid, objeid))
@@ -1105,22 +1102,22 @@
                         objects[objeid] = len(relations_by_rtype[rtype])
                         continue
                     objects[objeid] = len(relations_by_rtype[rtype])
-        for rtype, source_relations in relations_by_rtype.iteritems():
+        for rtype, source_relations in relations_by_rtype.items():
             self.hm.call_hooks('before_add_relation', cnx,
                                rtype=rtype, eids_from_to=source_relations)
-        for rtype, source_relations in relations_by_rtype.iteritems():
+        for rtype, source_relations in relations_by_rtype.items():
             source.add_relations(cnx, rtype, source_relations)
             rschema = self.schema.rschema(rtype)
             for subjeid, objeid in source_relations:
                 cnx.update_rel_cache_add(subjeid, rtype, objeid, rschema.symmetric)
-        for rtype, source_relations in relations_by_rtype.iteritems():
+        for rtype, source_relations in relations_by_rtype.items():
             self.hm.call_hooks('after_add_relation', cnx,
                                rtype=rtype, eids_from_to=source_relations)
 
     def glob_delete_relation(self, cnx, subject, rtype, object):
         """delete a relation from the repository"""
         if server.DEBUG & server.DBG_REPO:
-            print 'DELETE relation', subject, rtype, object
+            print('DELETE relation', subject, rtype, object)
         source = self.system_source
         self.hm.call_hooks('before_delete_relation', cnx,
                            eidfrom=subject, rtype=rtype, eidto=object)
--- a/server/rqlannotation.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/rqlannotation.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,6 +18,7 @@
 """Functions to add additional annotations on a rql syntax tree to ease later
 code generation.
 """
+from __future__ import print_function
 
 __docformat__ = "restructuredtext en"
 
@@ -33,7 +34,7 @@
     #if server.DEBUG:
     #    print '-------- sql annotate', repr(rqlst)
     getrschema = annotator.schema.rschema
-    for var in rqlst.defined_vars.itervalues():
+    for var in rqlst.defined_vars.values():
         stinfo = var.stinfo
         if stinfo.get('ftirels'):
             has_text_query = True
@@ -144,7 +145,7 @@
                 stinfo['invariant'] = False
     # see unittest_rqlannotation. test_has_text_security_cache_bug
     # XXX probably more to do, but yet that work without more...
-    for col_alias in rqlst.aliases.itervalues():
+    for col_alias in rqlst.aliases.values():
         if col_alias.stinfo.get('ftirels'):
             has_text_query = True
     return has_text_query
@@ -194,7 +195,7 @@
     # if DISTINCT query, can use variable from a different scope as principal
     # since introduced duplicates will be removed
     if scope.stmt.distinct and diffscope_rels:
-        return iter(_sort(diffscope_rels)).next()
+        return next(iter(_sort(diffscope_rels)))
     # XXX could use a relation from a different scope if it can't generate
     # duplicates, so we should have to check cardinality
     raise CantSelectPrincipal()
@@ -231,7 +232,7 @@
     for select in union.children:
         for subquery in select.with_:
             set_qdata(getrschema, subquery.query, noinvariant)
-        for var in select.defined_vars.itervalues():
+        for var in select.defined_vars.values():
             if var.stinfo['invariant']:
                 if var in noinvariant and not var.stinfo['principal'].r_type == 'has_text':
                     var._q_invariant = False
@@ -317,7 +318,7 @@
 
     def compute(self, rqlst):
         # set domains for each variable
-        for varname, var in rqlst.defined_vars.iteritems():
+        for varname, var in rqlst.defined_vars.items():
             if var.stinfo['uidrel'] is not None or \
                    self.eschema(rqlst.solutions[0][varname]).final:
                 ptypes = var.stinfo['possibletypes']
@@ -354,9 +355,9 @@
                     continue
 
     def _debug_print(self):
-        print 'varsols', dict((x, sorted(str(v) for v in values))
-                               for x, values in self.varsols.iteritems())
-        print 'ambiguous vars', sorted(self.ambiguousvars)
+        print('varsols', dict((x, sorted(str(v) for v in values))
+                               for x, values in self.varsols.items()))
+        print('ambiguous vars', sorted(self.ambiguousvars))
 
     def set_rel_constraint(self, term, rel, etypes_func):
         if isinstance(term, VariableRef) and self.is_ambiguous(term.variable):
--- a/server/schema2sql.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/schema2sql.py	Thu Dec 10 12:34:15 2015 +0100
@@ -162,8 +162,8 @@
 
 def check_constraint(eschema, aschema, attr, constraint, dbhelper, prefix=''):
     # XXX should find a better name
-    cstrname = 'cstr' + md5(eschema.type + attr + constraint.type() +
-                            (constraint.serialize() or '')).hexdigest()
+    cstrname = 'cstr' + md5((eschema.type + attr + constraint.type() +
+                             (constraint.serialize() or '')).encode('ascii')).hexdigest()
     if constraint.type() == 'BoundaryConstraint':
         value = as_sql(constraint.boundary, dbhelper, prefix)
         return cstrname, '%s%s %s %s' % (prefix, attr, constraint.operator, value)
--- a/server/schemaserial.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/schemaserial.py	Thu Dec 10 12:34:15 2015 +0100
@@ -16,6 +16,7 @@
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """functions for schema / permissions (de)serialization using RQL"""
+from __future__ import print_function
 
 __docformat__ = "restructuredtext en"
 
@@ -23,6 +24,8 @@
 import json
 import sys
 
+from six import PY2, text_type, string_types
+
 from logilab.common.shellutils import ProgressBar, DummyProgressBar
 
 from yams import BadSchemaDefinition, schema as schemamod, buildobjs as ybo
@@ -49,11 +52,11 @@
         return res
     missing = [g for g in ('owners', 'managers', 'users', 'guests') if not g in res]
     if missing:
-        print 'some native groups are missing but the following groups have been found:'
-        print '\n'.join('* %s (%s)' % (n, eid) for n, eid in res.items())
-        print
-        print 'enter the eid of a to group to map to each missing native group'
-        print 'or just type enter to skip permissions granted to a group'
+        print('some native groups are missing but the following groups have been found:')
+        print('\n'.join('* %s (%s)' % (n, eid) for n, eid in res.items()))
+        print()
+        print('enter the eid of a to group to map to each missing native group')
+        print('or just type enter to skip permissions granted to a group')
         for group in missing:
             while True:
                 value = raw_input('eid for group %s: ' % group).strip()
@@ -62,13 +65,13 @@
                 try:
                     eid = int(value)
                 except ValueError:
-                    print 'eid should be an integer'
+                    print('eid should be an integer')
                     continue
                 for eid_ in res.values():
                     if eid == eid_:
                         break
                 else:
-                    print 'eid is not a group eid'
+                    print('eid is not a group eid')
                     continue
                 res[name] = eid
                 break
@@ -146,7 +149,7 @@
                     {'x': etype, 'n': netype})
             cnx.commit(False)
             tocleanup = [eid]
-            tocleanup += (eid for eid, cached in repo._type_source_cache.iteritems()
+            tocleanup += (eid for eid, cached in repo._type_source_cache.items()
                           if etype == cached[0])
             repo.clear_caches(tocleanup)
             cnx.commit(False)
@@ -240,7 +243,7 @@
              'order', 'description', 'indexed', 'fulltextindexed',
              'internationalizable', 'default', 'formula'), values))
         typeparams = extra_props.get(attrs['rdefeid'])
-        attrs.update(json.load(typeparams) if typeparams else {})
+        attrs.update(json.loads(typeparams.getvalue().decode('ascii')) if typeparams else {})
         default = attrs['default']
         if default is not None:
             if isinstance(default, Binary):
@@ -281,7 +284,7 @@
         else:
             rtype = str(rel)
         relations[1].append(rtype)
-    for eschema, unique_together in unique_togethers.itervalues():
+    for eschema, unique_together in unique_togethers.values():
         eschema._unique_together.append(tuple(sorted(unique_together)))
     schema.infer_specialization_rules()
     cnx.commit()
@@ -331,7 +334,7 @@
         thispermsdict = permsidx[erschema.eid]
     except KeyError:
         return
-    for action, somethings in thispermsdict.iteritems():
+    for action, somethings in thispermsdict.items():
         erschema.permissions[action] = tuple(
             isinstance(p, tuple) and erschema.rql_expression(*p) or p
             for p in somethings)
@@ -344,7 +347,7 @@
     current schema
     """
     _title = '-> storing the schema in the database '
-    print _title,
+    print(_title, end=' ')
     execute = cnx.execute
     eschemas = schema.entities()
     pb_size = (len(eschemas + schema.relations())
@@ -366,7 +369,7 @@
     cstrtypemap = {}
     rql = 'INSERT CWConstraintType X: X name %(ct)s'
     for cstrtype in CONSTRAINTS:
-        cstrtypemap[cstrtype] = execute(rql, {'ct': unicode(cstrtype)},
+        cstrtypemap[cstrtype] = execute(rql, {'ct': text_type(cstrtype)},
                                         build_descr=False)[0][0]
         pb.update()
     # serialize relations
@@ -381,10 +384,10 @@
             continue
         execschemarql(execute, rschema, rschema2rql(rschema, addrdef=False))
         if rschema.symmetric:
-            rdefs = [rdef for k, rdef in rschema.rdefs.iteritems()
+            rdefs = [rdef for k, rdef in rschema.rdefs.items()
                      if (rdef.subject, rdef.object) == k]
         else:
-            rdefs = rschema.rdefs.itervalues()
+            rdefs = rschema.rdefs.values()
         for rdef in rdefs:
             execschemarql(execute, rdef,
                           rdef2rql(rdef, cstrtypemap, groupmap))
@@ -397,7 +400,7 @@
     for rql, kwargs in specialize2rql(schema):
         execute(rql, kwargs, build_descr=False)
         pb.update()
-    print
+    print()
 
 
 # high level serialization functions
@@ -455,8 +458,8 @@
     columnset = set()
     for columns in eschema._unique_together:
         if columns in columnset:
-            print ('schemaserial: skipping duplicate unique together %r %r' %
-                   (eschema.type, columns))
+            print('schemaserial: skipping duplicate unique together %r %r' %
+                  (eschema.type, columns))
             continue
         columnset.add(columns)
         rql, args = _uniquetogether2rql(eschema, columns)
@@ -471,7 +474,7 @@
     for i, name in enumerate(unique_together):
         rschema = eschema.schema.rschema(name)
         rtype = 'T%d' % i
-        substs[rtype] = unicode(rschema.type)
+        substs[rtype] = text_type(rschema.type)
         relations.append('C relations %s' % rtype)
         restrictions.append('%(rtype)s name %%(%(rtype)s)s' % {'rtype': rtype})
     relations = ', '.join(relations)
@@ -483,11 +486,11 @@
 
 def _ervalues(erschema):
     try:
-        type_ = unicode(erschema.type)
+        type_ = text_type(erschema.type)
     except UnicodeDecodeError as e:
         raise Exception("can't decode %s [was %s]" % (erschema.type, e))
     try:
-        desc = unicode(erschema.description) or u''
+        desc = text_type(erschema.description) or u''
     except UnicodeDecodeError as e:
         raise Exception("can't decode %s [was %s]" % (erschema.description, e))
     return {
@@ -509,7 +512,7 @@
     if addrdef:
         assert cstrtypemap
         # sort for testing purpose
-        for rdef in sorted(rschema.rdefs.itervalues(),
+        for rdef in sorted(rschema.rdefs.values(),
                            key=lambda x: (x.subject, x.object)):
             for rql, values in rdef2rql(rdef, cstrtypemap, groupmap):
                 yield rql, values
@@ -519,7 +522,7 @@
     values['final'] = rschema.final
     values['symmetric'] = rschema.symmetric
     values['inlined'] = rschema.inlined
-    if isinstance(rschema.fulltext_container, str):
+    if PY2 and isinstance(rschema.fulltext_container, str):
         values['fulltext_container'] = unicode(rschema.fulltext_container)
     else:
         values['fulltext_container'] = rschema.fulltext_container
@@ -535,7 +538,7 @@
 
 def crschema_relations_values(crschema):
     values = _ervalues(crschema)
-    values['rule'] = unicode(crschema.rule)
+    values['rule'] = text_type(crschema.rule)
     # XXX why oh why?
     del values['final']
     relations = ['X %s %%(%s)s' % (attr, attr) for attr in sorted(values)]
@@ -581,20 +584,20 @@
             value = bool(value)
         elif prop == 'ordernum':
             value = int(value)
-        elif isinstance(value, str):
+        elif PY2 and isinstance(value, str):
             value = unicode(value)
         if value is not None and prop == 'default':
             value = Binary.zpickle(value)
         values[amap.get(prop, prop)] = value
     if extra:
-        values['extra_props'] = Binary(json.dumps(extra))
+        values['extra_props'] = Binary(json.dumps(extra).encode('ascii'))
     relations = ['X %s %%(%s)s' % (attr, attr) for attr in sorted(values)]
     return relations, values
 
 def constraints2rql(cstrtypemap, constraints, rdefeid=None):
     for constraint in constraints:
         values = {'ct': cstrtypemap[constraint.type()],
-                  'value': unicode(constraint.serialize()),
+                  'value': text_type(constraint.serialize()),
                   'x': rdefeid} # when not specified, will have to be set by the caller
         yield 'INSERT CWConstraint X: X value %(value)s, X cstrtype CT, EDEF constrained_by X WHERE \
 CT eid %(ct)s, EDEF eid %(x)s', values
@@ -613,23 +616,23 @@
             # may occurs when modifying persistent schema
             continue
         for group_or_rqlexpr in grantedto:
-            if isinstance(group_or_rqlexpr, basestring):
+            if isinstance(group_or_rqlexpr, string_types):
                 # group
                 try:
                     yield ('SET X %s_permission Y WHERE Y eid %%(g)s, X eid %%(x)s' % action,
                            {'g': groupmap[group_or_rqlexpr]})
                 except KeyError:
-                    print ("WARNING: group %s used in permissions for %s was ignored because it doesn't exist."
-                           " You may want to add it into a precreate.py file" % (group_or_rqlexpr, erschema))
+                    print("WARNING: group %s used in permissions for %s was ignored because it doesn't exist."
+                          " You may want to add it into a precreate.py file" % (group_or_rqlexpr, erschema))
                     continue
             else:
                 # rqlexpr
                 rqlexpr = group_or_rqlexpr
                 yield ('INSERT RQLExpression E: E expression %%(e)s, E exprtype %%(t)s, '
                        'E mainvars %%(v)s, X %s_permission E WHERE X eid %%(x)s' % action,
-                       {'e': unicode(rqlexpr.expression),
-                        'v': unicode(','.join(sorted(rqlexpr.mainvars))),
-                        't': unicode(rqlexpr.__class__.__name__)})
+                       {'e': text_type(rqlexpr.expression),
+                        'v': text_type(','.join(sorted(rqlexpr.mainvars))),
+                        't': text_type(rqlexpr.__class__.__name__)})
 
 # update functions
 
@@ -641,7 +644,7 @@
 def updaterschema2rql(rschema, eid):
     if rschema.rule:
         yield ('SET X rule %(r)s WHERE X eid %(x)s',
-               {'x': eid, 'r': unicode(rschema.rule)})
+               {'x': eid, 'r': text_type(rschema.rule)})
     else:
         relations, values = rschema_relations_values(rschema)
         values['x'] = eid
--- a/server/serverconfig.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/serverconfig.py	Thu Dec 10 12:34:15 2015 +0100
@@ -16,12 +16,14 @@
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """server.serverconfig definition"""
+from __future__ import print_function
 
 __docformat__ = "restructuredtext en"
 
 import sys
 from os.path import join, exists
-from StringIO import StringIO
+
+from six.moves import StringIO
 
 import logilab.common.configuration as lgconfig
 from logilab.common.decorators import cached
@@ -234,18 +236,19 @@
 
     def bootstrap_cubes(self):
         from logilab.common.textutils import splitstrip
-        for line in file(join(self.apphome, 'bootstrap_cubes')):
-            line = line.strip()
-            if not line or line.startswith('#'):
-                continue
-            self.init_cubes(self.expand_cubes(splitstrip(line)))
-            break
-        else:
-            # no cubes
-            self.init_cubes(())
+        with open(join(self.apphome, 'bootstrap_cubes')) as f:
+            for line in f:
+                line = line.strip()
+                if not line or line.startswith('#'):
+                    continue
+                self.init_cubes(self.expand_cubes(splitstrip(line)))
+                break
+            else:
+                # no cubes
+                self.init_cubes(())
 
     def write_bootstrap_cubes_file(self, cubes):
-        stream = file(join(self.apphome, 'bootstrap_cubes'), 'w')
+        stream = open(join(self.apphome, 'bootstrap_cubes'), 'w')
         stream.write('# this is a generated file only used for bootstraping\n')
         stream.write('# you should not have to edit this\n')
         stream.write('%s\n' % ','.join(cubes))
@@ -276,7 +279,7 @@
                 assert len(self.sources_mode) == 1
                 if source.connect_for_migration:
                     return True
-                print 'not connecting to source', source.uri, 'during migration'
+                print('not connecting to source', source.uri, 'during migration')
                 return False
             if 'all' in self.sources_mode:
                 assert len(self.sources_mode) == 1
--- a/server/serverctl.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/serverctl.py	Thu Dec 10 12:34:15 2015 +0100
@@ -16,6 +16,7 @@
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """cubicweb-ctl commands and command handlers specific to the repository"""
+from __future__ import print_function
 
 __docformat__ = 'restructuredtext en'
 
@@ -28,6 +29,9 @@
 import logging
 import subprocess
 
+from six import string_types
+from six.moves import input
+
 from logilab.common import nullobject
 from logilab.common.configuration import Configuration, merge_options
 from logilab.common.shellutils import ASK, generate_password
@@ -55,27 +59,27 @@
     driver = source['db-driver']
     dbhelper = get_db_helper(driver)
     if interactive:
-        print '-> connecting to %s database' % driver,
+        print('-> connecting to %s database' % driver, end=' ')
         if dbhost:
-            print '%s@%s' % (dbname, dbhost),
+            print('%s@%s' % (dbname, dbhost), end=' ')
         else:
-            print dbname,
+            print(dbname, end=' ')
     if dbhelper.users_support:
         if not interactive or (not special_privs and source.get('db-user')):
             user = source.get('db-user', os.environ.get('USER', ''))
             if interactive:
-                print 'as', user
+                print('as', user)
             password = source.get('db-password')
         else:
-            print
+            print()
             if special_privs:
-                print 'WARNING'
+                print('WARNING')
                 print ('the user will need the following special access rights '
                        'on the database:')
-                print special_privs
-                print
+                print(special_privs)
+                print()
             default_user = source.get('db-user', os.environ.get('USER', ''))
-            user = raw_input('Connect as user ? [%r]: ' % default_user)
+            user = input('Connect as user ? [%r]: ' % default_user)
             user = user.strip() or default_user
             if user == source.get('db-user'):
                 password = source.get('db-password')
@@ -146,7 +150,7 @@
             cnx = repoapi.connect(repo, login, password=pwd)
             return repo, cnx
         except AuthenticationError:
-            print '-> Error: wrong user/password.'
+            print('-> Error: wrong user/password.')
             # reset cubes else we'll have an assertion error on next retry
             config._cubes = None
         login, pwd = manager_userpasswd()
@@ -164,9 +168,9 @@
         """
         config = self.config
         if not automatic:
-            print underline_title('Configuring the repository')
+            print(underline_title('Configuring the repository'))
             config.input_config('email', inputlevel)
-            print '\n'+underline_title('Configuring the sources')
+            print('\n'+underline_title('Configuring the sources'))
         sourcesfile = config.sources_file()
         # hack to make Method('default_instance_id') usable in db option defs
         # (in native.py)
@@ -174,12 +178,12 @@
                                       options=SOURCE_TYPES['native'].options)
         if not automatic:
             sconfig.input_config(inputlevel=inputlevel)
-            print
+            print()
         sourcescfg = {'system': sconfig}
         if automatic:
             # XXX modify a copy
             password = generate_password()
-            print '-> set administrator account to admin / %s' % password
+            print('-> set administrator account to admin / %s' % password)
             USER_OPTIONS[1][1]['default'] = password
             sconfig = Configuration(options=USER_OPTIONS)
         else:
@@ -197,8 +201,8 @@
             CWCTL.run(['db-create', '--config-level', str(inputlevel),
                        self.config.appid])
         else:
-            print ('-> nevermind, you can do it later with '
-                   '"cubicweb-ctl db-create %s".' % self.config.appid)
+            print('-> nevermind, you can do it later with '
+                  '"cubicweb-ctl db-create %s".' % self.config.appid)
 
 
 @contextmanager
@@ -242,26 +246,26 @@
         with db_transaction(source, privilege='DROP SCHEMA') as cursor:
             helper = get_db_helper(source['db-driver'])
             helper.drop_schema(cursor, db_namespace)
-            print '-> database schema %s dropped' % db_namespace
+            print('-> database schema %s dropped' % db_namespace)
 
     def _drop_database(self, source):
         dbname = source['db-name']
         if source['db-driver'] == 'sqlite':
-            print 'deleting database file %(db-name)s' % source
+            print('deleting database file %(db-name)s' % source)
             os.unlink(source['db-name'])
-            print '-> database %(db-name)s dropped.' % source
+            print('-> database %(db-name)s dropped.' % source)
         else:
             helper = get_db_helper(source['db-driver'])
             with db_sys_transaction(source, privilege='DROP DATABASE') as cursor:
-                print 'dropping database %(db-name)s' % source
+                print('dropping database %(db-name)s' % source)
                 cursor.execute('DROP DATABASE "%(db-name)s"' % source)
-                print '-> database %(db-name)s dropped.' % source
+                print('-> database %(db-name)s dropped.' % source)
 
     def _drop_user(self, source):
         user = source['db-user'] or None
         if user is not None:
             with db_sys_transaction(source, privilege='DROP USER') as cursor:
-                print 'dropping user %s' % user
+                print('dropping user %s' % user)
                 cursor.execute('DROP USER %s' % user)
 
     def _cleanup_steps(self, source):
@@ -288,7 +292,7 @@
                 try:
                     step(source)
                 except Exception as exc:
-                    print 'ERROR', exc
+                    print('ERROR', exc)
                     if ASK.confirm('An error occurred. Continue anyway?',
                                    default_is_yes=False):
                         continue
@@ -357,7 +361,7 @@
                 ASK.confirm('Database %s already exists. Drop it?' % dbname)):
                 os.unlink(dbname)
         elif self.config.create_db:
-            print '\n'+underline_title('Creating the system database')
+            print('\n'+underline_title('Creating the system database'))
             # connect on the dbms system base to create our base
             dbcnx = _db_sys_cnx(source, 'CREATE/DROP DATABASE and / or USER',
                                 interactive=not automatic)
@@ -368,17 +372,17 @@
                     if not helper.user_exists(cursor, user) and (automatic or \
                            ASK.confirm('Create db user %s ?' % user, default_is_yes=False)):
                         helper.create_user(source['db-user'], source.get('db-password'))
-                        print '-> user %s created.' % user
+                        print('-> user %s created.' % user)
                 if dbname in helper.list_databases(cursor):
                     if automatic or ASK.confirm('Database %s already exists -- do you want to drop it ?' % dbname):
                         cursor.execute('DROP DATABASE "%s"' % dbname)
                     else:
-                        print ('you may want to run "cubicweb-ctl db-init '
-                               '--drop %s" manually to continue.' % config.appid)
+                        print('you may want to run "cubicweb-ctl db-init '
+                              '--drop %s" manually to continue.' % config.appid)
                         return
                 createdb(helper, source, dbcnx, cursor)
                 dbcnx.commit()
-                print '-> database %s created.' % dbname
+                print('-> database %s created.' % dbname)
             except BaseException:
                 dbcnx.rollback()
                 raise
@@ -400,13 +404,13 @@
                     try:
                         helper.create_language(cursor, extlang)
                     except Exception as exc:
-                        print '-> ERROR:', exc
-                        print '-> could not create language %s, some stored procedures might be unusable' % extlang
+                        print('-> ERROR:', exc)
+                        print('-> could not create language %s, some stored procedures might be unusable' % extlang)
                         cnx.rollback()
                     else:
                         cnx.commit()
-        print '-> database for instance %s created and necessary extensions installed.' % appid
-        print
+        print('-> database for instance %s created and necessary extensions installed.' % appid)
+        print()
         if automatic:
             CWCTL.run(['db-init', '--automatic', '--config-level', '0',
                        config.appid])
@@ -414,8 +418,8 @@
             CWCTL.run(['db-init', '--config-level',
                        str(self.config.config_level), config.appid])
         else:
-            print ('-> nevermind, you can do it later with '
-                   '"cubicweb-ctl db-init %s".' % config.appid)
+            print('-> nevermind, you can do it later with '
+                  '"cubicweb-ctl db-init %s".' % config.appid)
 
 
 class InitInstanceCommand(Command):
@@ -452,7 +456,7 @@
 
     def run(self, args):
         check_options_consistency(self.config)
-        print '\n'+underline_title('Initializing the system database')
+        print('\n'+underline_title('Initializing the system database'))
         from cubicweb.server import init_repository
         appid = args[0]
         config = ServerConfiguration.config_for(appid)
@@ -503,10 +507,10 @@
                 used = set(n for n, in cnx.execute('Any SN WHERE S is CWSource, S name SN'))
                 cubes = repo.get_cubes()
                 while True:
-                    type = raw_input('source type (%s): '
+                    type = input('source type (%s): '
                                         % ', '.join(sorted(SOURCE_TYPES)))
                     if type not in SOURCE_TYPES:
-                        print '-> unknown source type, use one of the available types.'
+                        print('-> unknown source type, use one of the available types.')
                         continue
                     sourcemodule = SOURCE_TYPES[type].module
                     if not sourcemodule.startswith('cubicweb.'):
@@ -520,23 +524,23 @@
                             continue
                     break
                 while True:
-                    parser = raw_input('parser type (%s): '
+                    parser = input('parser type (%s): '
                                         % ', '.join(sorted(repo.vreg['parsers'])))
                     if parser in repo.vreg['parsers']:
                         break
-                    print '-> unknown parser identifier, use one of the available types.'
+                    print('-> unknown parser identifier, use one of the available types.')
                 while True:
-                    sourceuri = raw_input('source identifier (a unique name used to '
+                    sourceuri = input('source identifier (a unique name used to '
                                           'tell sources apart): ').strip()
                     if not sourceuri:
-                        print '-> mandatory.'
+                        print('-> mandatory.')
                     else:
                         sourceuri = unicode(sourceuri, sys.stdin.encoding)
                         if sourceuri in used:
-                            print '-> uri already used, choose another one.'
+                            print('-> uri already used, choose another one.')
                         else:
                             break
-                url = raw_input('source URL (leave empty for none): ').strip()
+                url = input('source URL (leave empty for none): ').strip()
                 url = unicode(url) if url else None
                 # XXX configurable inputlevel
                 sconfig = ask_source_config(config, type, inputlevel=self.config.config_level)
@@ -583,10 +587,10 @@
             cnx.rollback()
             import traceback
             traceback.print_exc()
-            print '-> an error occurred:', ex
+            print('-> an error occurred:', ex)
         else:
             cnx.commit()
-            print '-> rights granted to %s on instance %s.' % (appid, user)
+            print('-> rights granted to %s on instance %s.' % (appid, user))
 
 
 class ResetAdminPasswordCommand(Command):
@@ -617,7 +621,7 @@
         try:
             adminlogin = sourcescfg['admin']['login']
         except KeyError:
-            print '-> Error: could not get cubicweb administrator login.'
+            print('-> Error: could not get cubicweb administrator login.')
             sys.exit(1)
         cnx = source_cnx(sourcescfg['system'])
         driver = sourcescfg['system']['db-driver']
@@ -627,9 +631,9 @@
         cursor.execute("SELECT * FROM cw_CWUser WHERE cw_login=%(l)s",
                        {'l': adminlogin})
         if not cursor.fetchall():
-            print ("-> error: admin user %r specified in sources doesn't exist "
-                   "in the database" % adminlogin)
-            print "   fix your sources file before running this command"
+            print("-> error: admin user %r specified in sources doesn't exist "
+                  "in the database" % adminlogin)
+            print("   fix your sources file before running this command")
             cnx.close()
             sys.exit(1)
         if self.config.password is None:
@@ -650,10 +654,10 @@
             cnx.rollback()
             import traceback
             traceback.print_exc()
-            print '-> an error occurred:', ex
+            print('-> an error occurred:', ex)
         else:
             cnx.commit()
-            print '-> password reset, sources file regenerated.'
+            print('-> password reset, sources file regenerated.')
         cnx.close()
 
 
@@ -666,17 +670,17 @@
     if sudo:
         dmpcmd = 'sudo %s' % (dmpcmd)
     dmpcmd = 'ssh -t %s "%s"' % (host, dmpcmd)
-    print dmpcmd
+    print(dmpcmd)
     if os.system(dmpcmd):
         raise ExecutionError('Error while dumping the database')
     if output is None:
         output = filename
     cmd = 'scp %s:/tmp/%s %s' % (host, filename, output)
-    print cmd
+    print(cmd)
     if os.system(cmd):
         raise ExecutionError('Error while retrieving the dump at /tmp/%s' % filename)
     rmcmd = 'ssh -t %s "rm -f /tmp/%s"' % (host, filename)
-    print rmcmd
+    print(rmcmd)
     if os.system(rmcmd) and not ASK.confirm(
         'An error occurred while deleting remote dump at /tmp/%s. '
         'Continue anyway?' % filename):
@@ -686,7 +690,7 @@
 def _local_dump(appid, output, format='native'):
     config = ServerConfiguration.config_for(appid)
     config.quick_start = True
-    mih = config.migration_handler(connect=False, verbosity=1)
+    mih = config.migration_handler(verbosity=1)
     mih.backup_database(output, askconfirm=False, format=format)
     mih.shutdown()
 
@@ -696,28 +700,28 @@
     config.quick_start = True
     mih = config.migration_handler(connect=False, verbosity=1)
     mih.restore_database(backupfile, drop, askconfirm=False, format=format)
-    repo = mih.repo_connect()
+    repo = mih.repo
     # version of the database
     dbversions = repo.get_versions()
     mih.shutdown()
     if not dbversions:
-        print "bad or missing version information in the database, don't upgrade file system"
+        print("bad or missing version information in the database, don't upgrade file system")
         return
     # version of installed software
     eversion = dbversions['cubicweb']
     status = instance_status(config, eversion, dbversions)
     # * database version > installed software
     if status == 'needsoftupgrade':
-        print "** The database of %s is more recent than the installed software!" % config.appid
-        print "** Upgrade your software, then migrate the database by running the command"
-        print "** 'cubicweb-ctl upgrade %s'" % config.appid
+        print("** The database of %s is more recent than the installed software!" % config.appid)
+        print("** Upgrade your software, then migrate the database by running the command")
+        print("** 'cubicweb-ctl upgrade %s'" % config.appid)
         return
     # * database version < installed software, an upgrade will be necessary
     #   anyway, just rewrite vc.conf and warn user he has to upgrade
     elif status == 'needapplupgrade':
-        print "** The database of %s is older than the installed software." % config.appid
-        print "** Migrate the database by running the command"
-        print "** 'cubicweb-ctl upgrade %s'" % config.appid
+        print("** The database of %s is older than the installed software." % config.appid)
+        print("** Migrate the database by running the command")
+        print("** 'cubicweb-ctl upgrade %s'" % config.appid)
         return
     # * database version = installed software, database version = instance fs version
     #   ok!
@@ -732,12 +736,12 @@
         try:
             softversion = config.cube_version(cube)
         except ConfigurationError:
-            print '-> Error: no cube version information for %s, please check that the cube is installed.' % cube
+            print('-> Error: no cube version information for %s, please check that the cube is installed.' % cube)
             continue
         try:
             applversion = vcconf[cube]
         except KeyError:
-            print '-> Error: no cube version information for %s in version configuration.' % cube
+            print('-> Error: no cube version information for %s in version configuration.' % cube)
             continue
         if softversion == applversion:
             continue
@@ -883,7 +887,7 @@
         _local_restore(destappid, output, not self.config.no_drop,
                        self.config.format)
         if self.config.keep_dump:
-            print '-> you can get the dump file at', output
+            print('-> you can get the dump file at', output)
         else:
             os.remove(output)
 
@@ -1001,9 +1005,9 @@
                 stats = source.pull_data(cnx, force=True, raise_on_error=True)
         finally:
             repo.shutdown()
-        for key, val in stats.iteritems():
+        for key, val in stats.items():
             if val:
-                print key, ':', val
+                print(key, ':', val)
 
 
 
@@ -1019,7 +1023,7 @@
     for p in ('read', 'add', 'update', 'delete'):
         rule = perms.get(p)
         if rule:
-            perms[p] = tuple(str(x) if isinstance(x, basestring) else x
+            perms[p] = tuple(str(x) if isinstance(x, string_types) else x
                              for x in rule)
     return perms, perms in defaultrelperms or perms in defaulteperms
 
@@ -1079,7 +1083,7 @@
     if self.config.db is not None:
         appcfg = ServerConfiguration.config_for(appid)
         srccfg = appcfg.read_sources_file()
-        for key, value in self.config.db.iteritems():
+        for key, value in self.config.db.items():
             if '.' in key:
                 section, key = key.split('.', 1)
             else:
--- a/server/session.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/session.py	Thu Dec 10 12:34:15 2015 +0100
@@ -16,6 +16,8 @@
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """Repository users' and internal' sessions."""
+from __future__ import print_function
+
 __docformat__ = "restructuredtext en"
 
 import sys
@@ -25,6 +27,8 @@
 import functools
 from contextlib import contextmanager
 
+from six import text_type
+
 from logilab.common.deprecation import deprecated
 from logilab.common.textutils import unormalize
 from logilab.common.registry import objectify_predicate
@@ -556,7 +560,7 @@
                 else:
                     relations_dict[rtype] = eids
             self.repo.glob_add_relations(self, relations_dict)
-            for edited in edited_entities.itervalues():
+            for edited in edited_entities.values():
                 self.repo.glob_update_entity(self, edited)
 
 
@@ -769,7 +773,7 @@
     def transaction_uuid(self, set=True):
         uuid = self.transaction_data.get('tx_uuid')
         if set and uuid is None:
-            self.transaction_data['tx_uuid'] = uuid = unicode(uuid4().hex)
+            self.transaction_data['tx_uuid'] = uuid = text_type(uuid4().hex)
             self.repo.system_source.start_undoable_transaction(self, uuid)
         return uuid
 
@@ -874,7 +878,7 @@
                 processed = []
                 self.commit_state = 'precommit'
                 if debug:
-                    print self.commit_state, '*' * 20
+                    print(self.commit_state, '*' * 20)
                 try:
                     with self.running_hooks_ops():
                         while self.pending_operations:
@@ -882,7 +886,7 @@
                             operation.processed = 'precommit'
                             processed.append(operation)
                             if debug:
-                                print operation
+                                print(operation)
                             operation.handle_event('precommit_event')
                     self.pending_operations[:] = processed
                     self.debug('precommit transaction %s done', self.connectionid)
@@ -899,11 +903,11 @@
                     # and revertcommit, that will be enough in mont case.
                     operation.failed = True
                     if debug:
-                        print self.commit_state, '*' * 20
+                        print(self.commit_state, '*' * 20)
                     with self.running_hooks_ops():
                         for operation in reversed(processed):
                             if debug:
-                                print operation
+                                print(operation)
                             try:
                                 operation.handle_event('revertprecommit_event')
                             except BaseException:
@@ -917,12 +921,12 @@
                 self.cnxset.commit()
                 self.commit_state = 'postcommit'
                 if debug:
-                    print self.commit_state, '*' * 20
+                    print(self.commit_state, '*' * 20)
                 with self.running_hooks_ops():
                     while self.pending_operations:
                         operation = self.pending_operations.pop(0)
                         if debug:
-                            print operation
+                            print(operation)
                         operation.processed = 'postcommit'
                         try:
                             operation.handle_event('postcommit_event')
@@ -1004,7 +1008,7 @@
     """
 
     def __init__(self, user, repo, cnxprops=None, _id=None):
-        self.sessionid = _id or make_uid(unormalize(user.login).encode('UTF8'))
+        self.sessionid = _id or make_uid(unormalize(user.login))
         self.user = user # XXX repoapi: deprecated and store only a login.
         self.repo = repo
         self.vreg = repo.vreg
--- a/server/sources/__init__.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/sources/__init__.py	Thu Dec 10 12:34:15 2015 +0100
@@ -16,13 +16,18 @@
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """cubicweb server sources support"""
+from __future__ import print_function
 
 __docformat__ = "restructuredtext en"
 
 from time import time
 from logging import getLogger
+from base64 import b64decode
+
+from six import text_type
 
 from logilab.common import configuration
+from logilab.common.textutils import unormalize
 from logilab.common.deprecation import deprecated
 
 from yams.schema import role_name
@@ -35,25 +40,25 @@
 def dbg_st_search(uri, union, varmap, args, cachekey=None, prefix='rql for'):
     if server.DEBUG & server.DBG_RQL:
         global t
-        print '  %s %s source: %s' % (prefix, uri, repr(union.as_string()))
+        print('  %s %s source: %s' % (prefix, uri, repr(union.as_string())))
         t = time()
         if varmap:
-            print '    using varmap', varmap
+            print('    using varmap', varmap)
         if server.DEBUG & server.DBG_MORE:
-            print '    args', repr(args)
-            print '    cache key', cachekey
-            print '    solutions', ','.join(str(s.solutions)
-                                            for s in union.children)
+            print('    args', repr(args))
+            print('    cache key', cachekey)
+            print('    solutions', ','.join(str(s.solutions)
+                                            for s in union.children))
     # return true so it can be used as assertion (and so be killed by python -O)
     return True
 
 def dbg_results(results):
     if server.DEBUG & server.DBG_RQL:
         if len(results) > 10:
-            print '  -->', results[:10], '...', len(results),
+            print('  -->', results[:10], '...', len(results), end=' ')
         else:
-            print '  -->', results,
-        print 'time: ', time() - t
+            print('  -->', results, end=' ')
+        print('time: ', time() - t)
     # return true so it can be used as assertion (and so be killed by python -O)
     return True
 
@@ -104,7 +109,9 @@
         self.public_config['use-cwuri-as-url'] = self.use_cwuri_as_url
         self.remove_sensitive_information(self.public_config)
         self.uri = source_config.pop('uri')
-        set_log_methods(self, getLogger('cubicweb.sources.'+self.uri))
+        # unormalize to avoid non-ascii characters in logger's name, this will cause decoding error
+        # on logging
+        set_log_methods(self, getLogger('cubicweb.sources.' + unormalize(text_type(self.uri))))
         source_config.pop('type')
         self.update_config(None, self.check_conf_dict(eid, source_config,
                                                       fail_if_unknown=False))
@@ -140,7 +147,7 @@
         pass
 
     @classmethod
-    def check_conf_dict(cls, eid, confdict, _=unicode, fail_if_unknown=True):
+    def check_conf_dict(cls, eid, confdict, _=text_type, fail_if_unknown=True):
         """check configuration of source entity. Return config dict properly
         typed with defaults set.
         """
@@ -157,7 +164,7 @@
                 try:
                     value = configuration._validate(value, optdict, optname)
                 except Exception as ex:
-                    msg = unicode(ex) # XXX internationalization
+                    msg = text_type(ex) # XXX internationalization
                     raise ValidationError(eid, {role_name('config', 'subject'): msg})
             processed[optname] = value
         # cw < 3.10 bw compat
@@ -199,6 +206,12 @@
         else:
             self.urls = []
 
+    @staticmethod
+    def decode_extid(extid):
+        if extid is None:
+            return extid
+        return b64decode(extid)
+
     # source initialization / finalization #####################################
 
     def set_schema(self, schema):
--- a/server/sources/datafeed.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/sources/datafeed.py	Thu Dec 10 12:34:15 2015 +0100
@@ -19,15 +19,20 @@
 database
 """
 
-import urllib2
-import StringIO
+from io import BytesIO
 from os.path import exists
 from datetime import datetime, timedelta
-from base64 import b64decode
-from cookielib import CookieJar
-import urlparse
+
+from six import text_type
+from six.moves.urllib.parse import urlparse
+from six.moves.urllib.request import Request, build_opener, HTTPCookieProcessor
+from six.moves.urllib.error import HTTPError
+from six.moves.http_cookiejar import CookieJar
+
 from lxml import etree
 
+from logilab.common.deprecation import deprecated
+
 from cubicweb import RegistryNotFound, ObjectNotFound, ValidationError, UnknownEid
 from cubicweb.server.repository import preprocess_inlined_relations
 from cubicweb.server.sources import AbstractSource
@@ -244,6 +249,7 @@
                 error = True
         return error
 
+    @deprecated('[3.21] use the new store API')
     def before_entity_insertion(self, cnx, lid, etype, eid, sourceparams):
         """called by the repository when an eid has been attributed for an
         entity stored here but the entity has not been inserted in the system
@@ -259,6 +265,7 @@
         sourceparams['parser'].before_entity_copy(entity, sourceparams)
         return entity
 
+    @deprecated('[3.21] use the new store API')
     def after_entity_insertion(self, cnx, lid, entity, sourceparams):
         """called by the repository after an entity stored here has been
         inserted in the system table.
@@ -282,7 +289,7 @@
         sql = ('SELECT extid, eid, type FROM entities, cw_source_relation '
                'WHERE entities.eid=cw_source_relation.eid_from '
                'AND cw_source_relation.eid_to=%s' % self.eid)
-        return dict((b64decode(uri), (eid, type))
+        return dict((self.decode_extid(uri), (eid, type))
                     for uri, eid, type in cnx.system_sql(sql).fetchall())
 
     def init_import_log(self, cnx, **kwargs):
@@ -328,7 +335,7 @@
         For http URLs, it will try to find a cwclientlib config entry
         (if available) and use it as requester.
         """
-        purl = urlparse.urlparse(url)
+        purl = urlparse(url)
         if purl.scheme == 'file':
             return URLLibResponseAdapter(open(url[7:]), url)
 
@@ -344,7 +351,7 @@
             self.source.info('Using cwclientlib for %s' % url)
             resp = cnx.get(url)
             resp.raise_for_status()
-            return URLLibResponseAdapter(StringIO.StringIO(resp.text), url)
+            return URLLibResponseAdapter(BytesIO(resp.text), url)
         except (ImportError, ValueError, EnvironmentError) as exc:
             # ImportError: not available
             # ValueError: no config entry found
@@ -354,11 +361,11 @@
         # no chance with cwclientlib, fall back to former implementation
         if purl.scheme in ('http', 'https'):
             self.source.info('GET %s', url)
-            req = urllib2.Request(url)
+            req = Request(url)
             return _OPENER.open(req, timeout=self.source.http_timeout)
 
         # url is probably plain content
-        return URLLibResponseAdapter(StringIO.StringIO(url), url)
+        return URLLibResponseAdapter(BytesIO(url.encode('ascii')), url)
 
     def add_schema_config(self, schemacfg, checkonly=False):
         """added CWSourceSchemaConfig, modify mapping accordingly"""
@@ -370,6 +377,7 @@
         msg = schemacfg._cw._("this parser doesn't use a mapping")
         raise ValidationError(schemacfg.eid, {None: msg})
 
+    @deprecated('[3.21] use the new store API')
     def extid2entity(self, uri, etype, **sourceparams):
         """Return an entity for the given uri. May return None if it should be
         skipped.
@@ -388,11 +396,11 @@
         else:
             source = self.source
         sourceparams['parser'] = self
-        if isinstance(uri, unicode):
+        if isinstance(uri, text_type):
             uri = uri.encode('utf-8')
         try:
-            eid = cnx.repo.extid2eid(source, str(uri), etype, cnx,
-                                         sourceparams=sourceparams)
+            eid = cnx.repo.extid2eid(source, uri, etype, cnx,
+                                     sourceparams=sourceparams)
         except ValidationError as ex:
             if raise_on_error:
                 raise
@@ -419,9 +427,11 @@
         """main callback: process the url"""
         raise NotImplementedError
 
+    @deprecated('[3.21] use the new store API')
     def before_entity_copy(self, entity, sourceparams):
         raise NotImplementedError
 
+    @deprecated('[3.21] use the new store API')
     def after_entity_copy(self, entity, sourceparams):
         self.stats['created'].add(entity.eid)
 
@@ -447,10 +457,10 @@
     def handle_deletion(self, config, cnx, myuris):
         if config['delete-entities'] and myuris:
             byetype = {}
-            for extid, (eid, etype) in myuris.iteritems():
+            for extid, (eid, etype) in myuris.items():
                 if self.is_deleted(extid, etype, eid):
                     byetype.setdefault(etype, []).append(str(eid))
-            for etype, eids in byetype.iteritems():
+            for etype, eids in byetype.items():
                 self.warning('delete %s %s entities', len(eids), etype)
                 cnx.execute('DELETE %s X WHERE X eid IN (%s)'
                             % (etype, ','.join(eids)))
@@ -463,7 +473,7 @@
         self.notify_checked(entity)
         mdate = attrs.get('modification_date')
         if not mdate or mdate > entity.modification_date:
-            attrs = dict( (k, v) for k, v in attrs.iteritems()
+            attrs = dict( (k, v) for k, v in attrs.items()
                           if v != getattr(entity, k))
             if attrs:
                 entity.cw_set(**attrs)
@@ -472,6 +482,7 @@
 
 class DataFeedXMLParser(DataFeedParser):
 
+    @deprecated()
     def process(self, url, raise_on_error=False):
         """IDataFeedParser main entry point"""
         try:
@@ -530,10 +541,10 @@
             self.source.debug(str(exc))
 
         # no chance with cwclientlib, fall back to former implementation
-        if urlparse.urlparse(url).scheme in ('http', 'https'):
+        if urlparse(url).scheme in ('http', 'https'):
             try:
                 _OPENER.open(url, timeout=self.source.http_timeout)
-            except urllib2.HTTPError as ex:
+            except HTTPError as ex:
                 if ex.code == 404:
                     return True
         return False
@@ -555,15 +566,12 @@
     def getcode(self):
         return self.code
 
-    def info(self):
-        from mimetools import Message
-        return Message(StringIO.StringIO())
 
 # use a cookie enabled opener to use session cookie if any
-_OPENER = urllib2.build_opener()
+_OPENER = build_opener()
 try:
     from logilab.common import urllib2ext
     _OPENER.add_handler(urllib2ext.HTTPGssapiAuthHandler())
 except ImportError: # python-kerberos not available
     pass
-_OPENER.add_handler(urllib2.HTTPCookieProcessor(CookieJar()))
+_OPENER.add_handler(HTTPCookieProcessor(CookieJar()))
--- a/server/sources/ldapfeed.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/sources/ldapfeed.py	Thu Dec 10 12:34:15 2015 +0100
@@ -1,4 +1,4 @@
-# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2015 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
 # This file is part of CubicWeb.
@@ -17,14 +17,13 @@
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """cubicweb ldap feed source"""
 
-from __future__ import division # XXX why?
+from __future__ import division  # XXX why?
 
 from datetime import datetime
 
-import ldap
-from ldap.ldapobject import ReconnectLDAPObject
-from ldap.filter import filter_format
-from ldapurl import LDAPUrl
+from six import PY2, string_types
+
+import ldap3
 
 from logilab.common.configuration import merge_options
 
@@ -32,15 +31,15 @@
 from cubicweb.server import utils
 from cubicweb.server.sources import datafeed
 
-_ = unicode
+from cubicweb import _
 
 # search scopes
-BASE = ldap.SCOPE_BASE
-ONELEVEL = ldap.SCOPE_ONELEVEL
-SUBTREE = ldap.SCOPE_SUBTREE
-LDAP_SCOPES = {'BASE': ldap.SCOPE_BASE,
-               'ONELEVEL': ldap.SCOPE_ONELEVEL,
-               'SUBTREE': ldap.SCOPE_SUBTREE}
+BASE = ldap3.SEARCH_SCOPE_BASE_OBJECT
+ONELEVEL = ldap3.SEARCH_SCOPE_SINGLE_LEVEL
+SUBTREE = ldap3.SEARCH_SCOPE_WHOLE_SUBTREE
+LDAP_SCOPES = {'BASE': BASE,
+               'ONELEVEL': ONELEVEL,
+               'SUBTREE': SUBTREE}
 
 # map ldap protocol to their standard port
 PROTO_PORT = {'ldap': 389,
@@ -49,6 +48,15 @@
               }
 
 
+def replace_filter(s):
+    s = s.replace('*', '\\2A')
+    s = s.replace('(', '\\28')
+    s = s.replace(')', '\\29')
+    s = s.replace('\\', '\\5c')
+    s = s.replace('\0', '\\00')
+    return s
+
+
 class LDAPFeedSource(datafeed.DataFeedSource):
     """LDAP feed source: unlike ldapuser source, this source is copy based and
     will import ldap content (beside passwords for authentication) into the
@@ -61,7 +69,7 @@
         ('auth-mode',
          {'type' : 'choice',
           'default': 'simple',
-          'choices': ('simple', 'cram_md5', 'digest_md5', 'gssapi'),
+          'choices': ('simple', 'digest_md5', 'gssapi'),
           'help': 'authentication mode used to authenticate user to the ldap.',
           'group': 'ldap-source', 'level': 3,
           }),
@@ -183,8 +191,8 @@
         self.user_default_groups = typedconfig['user-default-group']
         self.user_attrs = {'dn': 'eid', 'modifyTimestamp': 'modification_date'}
         self.user_attrs.update(typedconfig['user-attrs-map'])
-        self.user_rev_attrs = dict((v, k) for k, v in self.user_attrs.iteritems())
-        self.base_filters = [filter_format('(%s=%s)', ('objectClass', o))
+        self.user_rev_attrs = dict((v, k) for k, v in self.user_attrs.items())
+        self.base_filters = ['(objectclass=%s)' % replace_filter(o)
                              for o in typedconfig['user-classes']]
         if typedconfig['user-filter']:
             self.base_filters.append(typedconfig['user-filter'])
@@ -193,8 +201,8 @@
         self.group_attrs = typedconfig['group-attrs-map']
         self.group_attrs = {'dn': 'eid', 'modifyTimestamp': 'modification_date'}
         self.group_attrs.update(typedconfig['group-attrs-map'])
-        self.group_rev_attrs = dict((v, k) for k, v in self.group_attrs.iteritems())
-        self.group_base_filters = [filter_format('(%s=%s)', ('objectClass', o))
+        self.group_rev_attrs = dict((v, k) for k, v in self.group_attrs.items())
+        self.group_base_filters = ['(objectClass=%s)' % replace_filter(o)
                                    for o in typedconfig['group-classes']]
         if typedconfig['group-filter']:
             self.group_base_filters.append(typedconfig['group-filter'])
@@ -215,9 +223,11 @@
     def connection_info(self):
         assert len(self.urls) == 1, self.urls
         protocol, hostport = self.urls[0].split('://')
-        if protocol != 'ldapi' and not ':' in hostport:
-            hostport = '%s:%s' % (hostport, PROTO_PORT[protocol])
-        return protocol, hostport
+        if protocol != 'ldapi' and ':' in hostport:
+            host, port = hostport.rsplit(':', 1)
+        else:
+            host, port = hostport, PROTO_PORT[protocol]
+        return protocol, host, port
 
     def authenticate(self, cnx, login, password=None, **kwargs):
         """return CWUser eid for the given login/password if this account is
@@ -232,59 +242,43 @@
             # You get Authenticated as: 'NT AUTHORITY\ANONYMOUS LOGON'.
             # we really really don't want that
             raise AuthenticationError()
-        searchfilter = [filter_format('(%s=%s)', (self.user_login_attr, login))]
+        searchfilter = ['(%s=%s)' % (replace_filter(self.user_login_attr), replace_filter(login))]
         searchfilter.extend(self.base_filters)
         searchstr = '(&%s)' % ''.join(searchfilter)
         # first search the user
         try:
             user = self._search(cnx, self.user_base_dn,
                                 self.user_base_scope, searchstr)[0]
-        except (IndexError, ldap.SERVER_DOWN):
+        except IndexError:
             # no such user
             raise AuthenticationError()
         # check password by establishing a (unused) connection
         try:
             self._connect(user, password)
-        except ldap.LDAPError as ex:
+        except ldap3.LDAPException as ex:
             # Something went wrong, most likely bad credentials
             self.info('while trying to authenticate %s: %s', user, ex)
             raise AuthenticationError()
         except Exception:
             self.error('while trying to authenticate %s', user, exc_info=True)
             raise AuthenticationError()
-        eid = self.repo.extid2eid(self, user['dn'], 'CWUser', cnx, insert=False)
-        if eid < 0:
-            # user has been moved away from this source
+        eid = self.repo.system_source.extid2eid(cnx, user['dn'].encode('ascii'))
+        if eid is None or eid < 0:
+            # user is not known or has been moved away from this source
             raise AuthenticationError()
         return eid
 
     def _connect(self, user=None, userpwd=None):
-        protocol, hostport = self.connection_info()
-        self.info('connecting %s://%s as %s', protocol, hostport,
+        protocol, host, port = self.connection_info()
+        self.info('connecting %s://%s:%s as %s', protocol, host, port,
                   user and user['dn'] or 'anonymous')
-        # don't require server certificate when using ldaps (will
-        # enable self signed certs)
-        ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
-        url = LDAPUrl(urlscheme=protocol, hostport=hostport)
-        conn = ReconnectLDAPObject(url.initializeUrl())
-        # Set the protocol version - version 3 is preferred
-        try:
-            conn.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION3)
-        except ldap.LDAPError: # Invalid protocol version, fall back safely
-            conn.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION2)
-        # Deny auto-chasing of referrals to be safe, we handle them instead
-        # Required for AD
-        try:
-            conn.set_option(ldap.OPT_REFERRALS, 0)
-        except ldap.LDAPError: # Cannot set referrals, so do nothing
-            pass
-        #conn.set_option(ldap.OPT_NETWORK_TIMEOUT, conn_timeout)
-        #conn.timeout = op_timeout
+        server = ldap3.Server(host, port=int(port))
+        conn = ldap3.Connection(server, user=user and user['dn'], client_strategy=ldap3.STRATEGY_SYNC_RESTARTABLE, auto_referrals=False)
         # Now bind with the credentials given. Let exceptions propagate out.
         if user is None:
             # XXX always use simple bind for data connection
             if not self.cnx_dn:
-                conn.simple_bind_s(self.cnx_dn, self.cnx_pwd)
+                conn.bind()
             else:
                 self._authenticate(conn, {'dn': self.cnx_dn}, self.cnx_pwd)
         else:
@@ -294,25 +288,22 @@
         return conn
 
     def _auth_simple(self, conn, user, userpwd):
-        conn.simple_bind_s(user['dn'], userpwd)
-
-    def _auth_cram_md5(self, conn, user, userpwd):
-        from ldap import sasl
-        auth_token = sasl.cram_md5(user['dn'], userpwd)
-        conn.sasl_interactive_bind_s('', auth_token)
+        conn.authentication = ldap3.AUTH_SIMPLE
+        conn.user = user['dn']
+        conn.password = userpwd
+        conn.bind()
 
     def _auth_digest_md5(self, conn, user, userpwd):
-        from ldap import sasl
-        auth_token = sasl.digest_md5(user['dn'], userpwd)
-        conn.sasl_interactive_bind_s('', auth_token)
+        conn.authentication = ldap3.AUTH_SASL
+        conn.sasl_mechanism = 'DIGEST-MD5'
+        # realm, user, password, authz-id
+        conn.sasl_credentials = (None, user['dn'], userpwd, None)
+        conn.bind()
 
     def _auth_gssapi(self, conn, user, userpwd):
-        # print XXX not proper sasl/gssapi
-        import kerberos
-        if not kerberos.checkPassword(user[self.user_login_attr], userpwd):
-            raise Exception('BAD login / mdp')
-        #from ldap import sasl
-        #conn.sasl_interactive_bind_s('', sasl.gssapi())
+        conn.authentication = ldap3.AUTH_SASL
+        conn.sasl_mechanism = 'GSSAPI'
+        conn.bind()
 
     def _search(self, cnx, base, scope,
                 searchstr='(objectClass=*)', attrs=()):
@@ -322,37 +313,15 @@
         if self._conn is None:
             self._conn = self._connect()
         ldapcnx = self._conn
-        try:
-            res = ldapcnx.search_s(base, scope, searchstr, attrs)
-        except ldap.PARTIAL_RESULTS:
-            res = ldapcnx.result(all=0)[1]
-        except ldap.NO_SUCH_OBJECT:
-            self.info('ldap NO SUCH OBJECT %s %s %s', base, scope, searchstr)
-            self._process_no_such_object(cnx, base)
+        if not ldapcnx.search(base, searchstr, search_scope=scope, attributes=attrs):
             return []
-        # except ldap.REFERRAL as e:
-        #     ldapcnx = self.handle_referral(e)
-        #     try:
-        #         res = ldapcnx.search_s(base, scope, searchstr, attrs)
-        #     except ldap.PARTIAL_RESULTS:
-        #         res_type, res = ldapcnx.result(all=0)
         result = []
-        for rec_dn, rec_dict in res:
-            # When used against Active Directory, "rec_dict" may not be
-            # be a dictionary in some cases (instead, it can be a list)
-            #
-            # An example of a useless "res" entry that can be ignored
-            # from AD is
-            # (None, ['ldap://ForestDnsZones.PORTAL.LOCAL/DC=ForestDnsZones,DC=PORTAL,DC=LOCAL'])
-            # This appears to be some sort of internal referral, but
-            # we can't handle it, so we need to skip over it.
-            try:
-                items = rec_dict.iteritems()
-            except AttributeError:
+        for rec in ldapcnx.response:
+            if rec['type'] != 'searchResEntry':
                 continue
-            else:
-                itemdict = self._process_ldap_item(rec_dn, items)
-                result.append(itemdict)
+            items = rec['attributes'].items()
+            itemdict = self._process_ldap_item(rec['dn'], items)
+            result.append(itemdict)
         self.debug('ldap built results %s', len(result))
         return result
 
@@ -363,20 +332,21 @@
             if self.user_attrs.get(key) == 'upassword': # XXx better password detection
                 value = value[0].encode('utf-8')
                 # we only support ldap_salted_sha1 for ldap sources, see: server/utils.py
-                if not value.startswith('{SSHA}'):
+                if not value.startswith(b'{SSHA}'):
                     value = utils.crypt_password(value)
                 itemdict[key] = Binary(value)
             elif self.user_attrs.get(key) == 'modification_date':
                 itemdict[key] = datetime.strptime(value[0], '%Y%m%d%H%M%SZ')
             else:
-                value = [unicode(val, 'utf-8', 'replace') for val in value]
+                if PY2 and value and isinstance(value[0], str):
+                    value = [unicode(val, 'utf-8', 'replace') for val in value]
                 if len(value) == 1:
                     itemdict[key] = value = value[0]
                 else:
                     itemdict[key] = value
         # we expect memberUid to be a list of user ids, make sure of it
         member = self.group_rev_attrs['member']
-        if isinstance(itemdict.get(member), basestring):
+        if isinstance(itemdict.get(member), string_types):
             itemdict[member] = [itemdict[member]]
         return itemdict
 
--- a/server/sources/native.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/sources/native.py	Thu Dec 10 12:34:15 2015 +0100
@@ -23,13 +23,13 @@
   string. This is because it should actually be Bytes but we want an index on
   it for fast querying.
 """
+from __future__ import print_function
+
 __docformat__ = "restructuredtext en"
 
-from cPickle import loads, dumps
-import cPickle as pickle
 from threading import Lock
 from datetime import datetime
-from base64 import b64decode, b64encode
+from base64 import b64encode
 from contextlib import contextmanager
 from os.path import basename
 import re
@@ -38,6 +38,9 @@
 import logging
 import sys
 
+from six import PY2, text_type, binary_type, string_types
+from six.moves import range, cPickle as pickle
+
 from logilab.common.decorators import cached, clear_cache
 from logilab.common.configuration import Method
 from logilab.common.shellutils import getlogin
@@ -76,12 +79,12 @@
         it's a function just so that it shows up in profiling
         """
         if server.DEBUG & server.DBG_SQL:
-            print 'exec', query, args
+            print('exec', query, args)
         try:
             self.cu.execute(str(query), args)
         except Exception as ex:
-            print "sql: %r\n args: %s\ndbms message: %r" % (
-                query, args, ex.args[0])
+            print("sql: %r\n args: %s\ndbms message: %r" % (
+                query, args, ex.args[0]))
             raise
 
     def fetchall(self):
@@ -134,7 +137,7 @@
 
         Type of _UndoException message must be `unicode` by design in CubicWeb.
         """
-        assert isinstance(self.args[0], unicode)
+        assert isinstance(self.args[0], text_type)
         return self.args[0]
 
 
@@ -556,7 +559,7 @@
                 sql, qargs, cbs = self._rql_sqlgen.generate(union, args, varmap)
                 self._cache[cachekey] = sql, qargs, cbs
         args = self.merge_args(args, qargs)
-        assert isinstance(sql, basestring), repr(sql)
+        assert isinstance(sql, string_types), repr(sql)
         cursor = self.doexec(cnx, sql, args)
         results = self.process_result(cursor, cnx, cbs)
         assert dbg_results(results)
@@ -611,7 +614,7 @@
             self.doexec(cnx, sql, attrs)
             if cnx.ertype_supports_undo(entity.cw_etype):
                 self._record_tx_action(cnx, 'tx_entity_actions', u'C',
-                                       etype=unicode(entity.cw_etype), eid=entity.eid)
+                                       etype=text_type(entity.cw_etype), eid=entity.eid)
 
     def update_entity(self, cnx, entity):
         """replace an entity in the source"""
@@ -620,8 +623,8 @@
             if cnx.ertype_supports_undo(entity.cw_etype):
                 changes = self._save_attrs(cnx, entity, attrs)
                 self._record_tx_action(cnx, 'tx_entity_actions', u'U',
-                                       etype=unicode(entity.cw_etype), eid=entity.eid,
-                                       changes=self._binary(dumps(changes)))
+                                       etype=text_type(entity.cw_etype), eid=entity.eid,
+                                       changes=self._binary(pickle.dumps(changes)))
             sql = self.sqlgen.update(SQL_PREFIX + entity.cw_etype, attrs,
                                      ['cw_eid'])
             self.doexec(cnx, sql, attrs)
@@ -635,8 +638,8 @@
                          if (r.final or r.inlined) and not r in VIRTUAL_RTYPES]
                 changes = self._save_attrs(cnx, entity, attrs)
                 self._record_tx_action(cnx, 'tx_entity_actions', u'D',
-                                       etype=unicode(entity.cw_etype), eid=entity.eid,
-                                       changes=self._binary(dumps(changes)))
+                                       etype=text_type(entity.cw_etype), eid=entity.eid,
+                                       changes=self._binary(pickle.dumps(changes)))
             attrs = {'cw_eid': entity.eid}
             sql = self.sqlgen.delete(SQL_PREFIX + entity.cw_etype, attrs)
             self.doexec(cnx, sql, attrs)
@@ -646,7 +649,7 @@
         self._add_relations(cnx,  rtype, [(subject, object)], inlined)
         if cnx.ertype_supports_undo(rtype):
             self._record_tx_action(cnx, 'tx_relation_actions', u'A',
-                                   eid_from=subject, rtype=unicode(rtype), eid_to=object)
+                                   eid_from=subject, rtype=text_type(rtype), eid_to=object)
 
     def add_relations(self, cnx,  rtype, subj_obj_list, inlined=False):
         """add a relations to the source"""
@@ -654,7 +657,7 @@
         if cnx.ertype_supports_undo(rtype):
             for subject, object in subj_obj_list:
                 self._record_tx_action(cnx, 'tx_relation_actions', u'A',
-                                       eid_from=subject, rtype=unicode(rtype), eid_to=object)
+                                       eid_from=subject, rtype=text_type(rtype), eid_to=object)
 
     def _add_relations(self, cnx, rtype, subj_obj_list, inlined=False):
         """add a relation to the source"""
@@ -671,7 +674,7 @@
                     etypes[etype].append((subject, object))
                 else:
                     etypes[etype] = [(subject, object)]
-            for subj_etype, subj_obj_list in etypes.iteritems():
+            for subj_etype, subj_obj_list in etypes.items():
                 attrs = [{'cw_eid': subject, SQL_PREFIX + rtype: object}
                          for subject, object in subj_obj_list]
                 sql.append((self.sqlgen.update(SQL_PREFIX + etype, attrs[0],
@@ -686,7 +689,7 @@
         self._delete_relation(cnx, subject, rtype, object, rschema.inlined)
         if cnx.ertype_supports_undo(rtype):
             self._record_tx_action(cnx, 'tx_relation_actions', u'R',
-                                   eid_from=subject, rtype=unicode(rtype), eid_to=object)
+                                   eid_from=subject, rtype=text_type(rtype), eid_to=object)
 
     def _delete_relation(self, cnx, subject, rtype, object, inlined=False):
         """delete a relation from the source"""
@@ -708,7 +711,7 @@
         """
         cursor = cnx.cnxset.cu
         if server.DEBUG & server.DBG_SQL:
-            print 'exec', query, args, cnx.cnxset.cnx
+            print('exec', query, args, cnx.cnxset.cnx)
         try:
             # str(query) to avoid error if it's a unicode string
             cursor.execute(str(query), args)
@@ -767,7 +770,7 @@
         it's a function just so that it shows up in profiling
         """
         if server.DEBUG & server.DBG_SQL:
-            print 'execmany', query, 'with', len(args), 'arguments', cnx.cnxset.cnx
+            print('execmany', query, 'with', len(args), 'arguments', cnx.cnxset.cnx)
         cursor = cnx.cnxset.cu
         try:
             # str(query) to avoid error if it's a unicode string
@@ -852,10 +855,9 @@
         """return a tuple (type, extid, source) for the entity with id <eid>"""
         sql = 'SELECT type, extid, asource FROM entities WHERE eid=%s' % eid
         res = self._eid_type_source(cnx, eid, sql)
-        if res[-2] is not None:
-            if not isinstance(res, list):
-                res = list(res)
-            res[-2] = b64decode(res[-2])
+        if not isinstance(res, list):
+            res = list(res)
+        res[-2] = self.decode_extid(res[-2])
         return res
 
     def eid_type_source_pre_131(self, cnx, eid):
@@ -864,15 +866,14 @@
         res = self._eid_type_source(cnx, eid, sql)
         if not isinstance(res, list):
             res = list(res)
-        if res[-1] is not None:
-            res[-1] = b64decode(res[-1])
+        res[-1] = self.decode_extid(res[-1])
         res.append("system")
         return res
 
     def extid2eid(self, cnx, extid):
         """get eid from an external id. Return None if no record found."""
-        assert isinstance(extid, str)
-        args = {'x': b64encode(extid)}
+        assert isinstance(extid, binary_type)
+        args = {'x': b64encode(extid).decode('ascii')}
         cursor = self.doexec(cnx,
                              'SELECT eid FROM entities WHERE extid=%(x)s',
                              args)
@@ -911,10 +912,10 @@
         assert cnx.cnxset is not None
         # begin by inserting eid/type/source/extid into the entities table
         if extid is not None:
-            assert isinstance(extid, str)
-            extid = b64encode(extid)
-        attrs = {'type': unicode(entity.cw_etype), 'eid': entity.eid, 'extid': extid and unicode(extid),
-                 'asource': unicode(source.uri)}
+            assert isinstance(extid, binary_type)
+            extid = b64encode(extid).decode('ascii')
+        attrs = {'type': text_type(entity.cw_etype), 'eid': entity.eid, 'extid': extid,
+                 'asource': text_type(source.uri)}
         self._handle_insert_entity_sql(cnx, self.sqlgen.insert('entities', attrs), attrs)
         # insert core relations: is, is_instance_of and cw_source
         try:
@@ -975,13 +976,13 @@
             if actionfilters.pop('public', True):
                 genrestr['txa_public'] = True
             # put additional filters in trarestr and/or tearestr
-            for key, val in actionfilters.iteritems():
+            for key, val in actionfilters.items():
                 if key == 'etype':
                     # filtering on etype implies filtering on entity actions
                     # only, and with no eid specified
                     assert actionfilters.get('action', 'C') in 'CUD'
                     assert not 'eid' in actionfilters
-                    tearestr['etype'] = unicode(val)
+                    tearestr['etype'] = text_type(val)
                 elif key == 'eid':
                     # eid filter may apply to 'eid' of tx_entity_actions or to
                     # 'eid_from' OR 'eid_to' of tx_relation_actions
@@ -992,10 +993,10 @@
                         trarestr['eid_to'] = val
                 elif key == 'action':
                     if val in 'CUD':
-                        tearestr['txa_action'] = unicode(val)
+                        tearestr['txa_action'] = text_type(val)
                     else:
                         assert val in 'AR'
-                        trarestr['txa_action'] = unicode(val)
+                        trarestr['txa_action'] = text_type(val)
                 else:
                     raise AssertionError('unknow filter %s' % key)
             assert trarestr or tearestr, "can't only filter on 'public'"
@@ -1029,11 +1030,11 @@
 
     def tx_info(self, cnx, txuuid):
         """See :class:`cubicweb.repoapi.Connection.transaction_info`"""
-        return tx.Transaction(cnx, txuuid, *self._tx_info(cnx, unicode(txuuid)))
+        return tx.Transaction(cnx, txuuid, *self._tx_info(cnx, text_type(txuuid)))
 
     def tx_actions(self, cnx, txuuid, public):
         """See :class:`cubicweb.repoapi.Connection.transaction_actions`"""
-        txuuid = unicode(txuuid)
+        txuuid = text_type(txuuid)
         self._tx_info(cnx, txuuid)
         restr = {'tx_uuid': txuuid}
         if public:
@@ -1044,7 +1045,7 @@
                                   'etype', 'eid', 'changes'))
         with cnx.ensure_cnx_set:
             cu = self.doexec(cnx, sql, restr)
-            actions = [tx.EntityAction(a,p,o,et,e,c and loads(self.binary_to_str(c)))
+            actions = [tx.EntityAction(a,p,o,et,e,c and pickle.loads(self.binary_to_str(c)))
                        for a,p,o,et,e,c in cu.fetchall()]
         sql = self.sqlgen.select('tx_relation_actions', restr,
                                  ('txa_action', 'txa_public', 'txa_order',
@@ -1168,8 +1169,8 @@
             elif eschema.destination(rtype) in ('Bytes', 'Password'):
                 changes[column] = self._binary(value)
                 edited[rtype] = Binary(value)
-            elif isinstance(value, str):
-                edited[rtype] = unicode(value, cnx.encoding, 'replace')
+            elif PY2 and isinstance(value, str):
+                edited[rtype] = text_type(value, cnx.encoding, 'replace')
             else:
                 edited[rtype] = value
         # This must only be done after init_entitiy_caches : defered in calling functions
@@ -1210,14 +1211,14 @@
         try:
             sentity, oentity, rdef = _undo_rel_info(cnx, subj, rtype, obj)
         except _UndoException as ex:
-            errors.append(unicode(ex))
+            errors.append(text_type(ex))
         else:
             for role, entity in (('subject', sentity),
                                  ('object', oentity)):
                 try:
                     _undo_check_relation_target(entity, rdef, role)
                 except _UndoException as ex:
-                    errors.append(unicode(ex))
+                    errors.append(text_type(ex))
                     continue
         if not errors:
             self.repo.hm.call_hooks('before_add_relation', cnx,
@@ -1293,7 +1294,7 @@
         try:
             sentity, oentity, rdef = _undo_rel_info(cnx, subj, rtype, obj)
         except _UndoException as ex:
-            errors.append(unicode(ex))
+            errors.append(text_type(ex))
         else:
             rschema = rdef.rtype
             if rschema.inlined:
@@ -1544,7 +1545,7 @@
                                         SQL_PREFIX + 'CWUser',
                                         SQL_PREFIX + 'upassword',
                                         SQL_PREFIX + 'login'),
-                                       {'newhash': self.source._binary(newhash),
+                                       {'newhash': self.source._binary(newhash.encode('ascii')),
                                         'login': login})
                     cnx.commit()
             return user
@@ -1692,7 +1693,7 @@
         self.logger.info('number of rows: %d', rowcount)
         blocksize = self.blocksize
         if rowcount > 0:
-            for i, start in enumerate(xrange(0, rowcount, blocksize)):
+            for i, start in enumerate(range(0, rowcount, blocksize)):
                 rows = list(itertools.islice(rows_iterator, blocksize))
                 serialized = self._serialize(table, columns, rows)
                 archive.writestr('tables/%s.%04d' % (table, i), serialized)
@@ -1713,7 +1714,7 @@
         return tuple(columns), rows
 
     def _serialize(self, name, columns, rows):
-        return dumps((name, columns, rows), pickle.HIGHEST_PROTOCOL)
+        return pickle.dumps((name, columns, rows), pickle.HIGHEST_PROTOCOL)
 
     def restore(self, backupfile):
         archive = zipfile.ZipFile(backupfile, 'r', allowZip64=True)
@@ -1761,7 +1762,7 @@
         return sequences, numranges, tables, table_chunks
 
     def read_sequence(self, archive, seq):
-        seqname, columns, rows = loads(archive.read('sequences/%s' % seq))
+        seqname, columns, rows = pickle.loads(archive.read('sequences/%s' % seq))
         assert seqname == seq
         assert len(rows) == 1
         assert len(rows[0]) == 1
@@ -1771,7 +1772,7 @@
         self.cnx.commit()
 
     def read_numrange(self, archive, numrange):
-        rangename, columns, rows = loads(archive.read('numrange/%s' % numrange))
+        rangename, columns, rows = pickle.loads(archive.read('numrange/%s' % numrange))
         assert rangename == numrange
         assert len(rows) == 1
         assert len(rows[0]) == 1
@@ -1786,7 +1787,7 @@
         self.cnx.commit()
         row_count = 0
         for filename in filenames:
-            tablename, columns, rows = loads(archive.read(filename))
+            tablename, columns, rows = pickle.loads(archive.read(filename))
             assert tablename == table
             if not rows:
                 continue
--- a/server/sources/rql2sql.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/sources/rql2sql.py	Thu Dec 10 12:34:15 2015 +0100
@@ -51,6 +51,9 @@
 
 import threading
 
+from six import PY2
+from six.moves import range
+
 from logilab.database import FunctionDescr, SQL_FUNCTIONS_REGISTRY
 
 from rql import BadRQLQuery, CoercionError
@@ -172,7 +175,7 @@
     existssols = {}
     unstable = set()
     invariants = {}
-    for vname, var in rqlst.defined_vars.iteritems():
+    for vname, var in rqlst.defined_vars.items():
         vtype = newsols[0][vname]
         if var._q_invariant or vname in varmap:
             # remove invariant variable from solutions to remove duplicates
@@ -187,13 +190,13 @@
                 thisexistssols = [newsols[0]]
                 thisexistsvars = set()
                 existssols[var.scope] = thisexistssols, thisexistsvars
-            for i in xrange(len(newsols)-1, 0, -1):
+            for i in range(len(newsols)-1, 0, -1):
                 if vtype != newsols[i][vname]:
                     thisexistssols.append(newsols.pop(i))
                     thisexistsvars.add(vname)
         else:
             # remember unstable variables
-            for i in xrange(1, len(newsols)):
+            for i in range(1, len(newsols)):
                 if vtype != newsols[i][vname]:
                     unstable.add(vname)
     if invariants:
@@ -205,11 +208,11 @@
         newsols = newsols_
         # reinsert solutions for invariants
         for sol in newsols:
-            for invvar, vartype in invariants[id(sol)].iteritems():
+            for invvar, vartype in invariants[id(sol)].items():
                 sol[invvar] = vartype
         for sol in existssols:
             try:
-                for invvar, vartype in invariants[id(sol)].iteritems():
+                for invvar, vartype in invariants[id(sol)].items():
                     sol[invvar] = vartype
             except KeyError:
                 continue
@@ -257,7 +260,7 @@
             append(term)
             if groups:
                 for vref in term.iget_nodes(VariableRef):
-                    if not vref in groups:
+                    if not any(vref.is_equivalent(g) for g in groups):
                         groups.append(vref)
 
 def fix_selection_and_group(rqlst, needwrap, selectsortterms,
@@ -273,7 +276,7 @@
                     (isinstance(term, Function) and
                      get_func_descr(term.name).aggregat)):
                 for vref in term.iget_nodes(VariableRef):
-                    if not vref in groupvrefs:
+                    if not any(vref.is_equivalent(group) for group in groupvrefs):
                         groups.append(vref)
                         groupvrefs.append(vref)
     if needwrap and (groups or having):
@@ -364,7 +367,7 @@
         self.done = set()
         self.tables = self.subtables.copy()
         self.actual_tables = [[]]
-        for _, tsql in self.tables.itervalues():
+        for _, tsql in self.tables.values():
             self.actual_tables[-1].append(tsql)
         self.outer_chains = []
         self.outer_tables = {}
@@ -398,7 +401,7 @@
         notdone_outside_vars = set()
         # when iterating other solutions inner to an EXISTS subquery, we should
         # reset variables which have this exists node as scope at each iteration
-        for var in exists.stmt.defined_vars.itervalues():
+        for var in exists.stmt.defined_vars.values():
             if var.scope is exists:
                 thisexistsvars.add(var.name)
             elif var.name not in self.done:
@@ -600,7 +603,7 @@
             self.outer_chains.remove(lchain)
             rchain += lchain
             self.mark_as_used_in_outer_join(leftalias)
-            for alias, (aouter, aconditions, achain) in outer_tables.iteritems():
+            for alias, (aouter, aconditions, achain) in outer_tables.items():
                 if achain is lchain:
                     outer_tables[alias] = (aouter, aconditions, rchain)
         else:
@@ -1475,7 +1478,7 @@
         """generate SQL name for a function"""
         if func.name == 'FTIRANK':
             try:
-                rel = iter(func.children[0].variable.stinfo['ftirels']).next()
+                rel = next(iter(func.children[0].variable.stinfo['ftirels']))
             except KeyError:
                 raise BadRQLQuery("can't use FTIRANK on variable not used in an"
                                   " 'has_text' relation (eg full-text search)")
@@ -1512,7 +1515,7 @@
                 return self._mapped_term(constant, '%%(%s)s' % value)[0]
             except KeyError:
                 _id = value
-                if isinstance(_id, unicode):
+                if PY2 and isinstance(_id, unicode):
                     _id = _id.encode()
         else:
             _id = str(id(constant)).replace('-', '', 1)
@@ -1561,7 +1564,7 @@
                     # add additional restriction on entities.type column
                     pts = variable.stinfo['possibletypes']
                     if len(pts) == 1:
-                        etype = iter(variable.stinfo['possibletypes']).next()
+                        etype = next(iter(variable.stinfo['possibletypes']))
                         restr = "%s.type='%s'" % (vtablename, etype)
                     else:
                         etypes = ','.join("'%s'" % et for et in pts)
@@ -1609,7 +1612,7 @@
 
     def _temp_table_scope(self, select, table):
         scope = 9999
-        for var, sql in self._varmap.iteritems():
+        for var, sql in self._varmap.items():
             # skip "attribute variable" in varmap (such 'T.login')
             if not '.' in var and table == sql.split('.', 1)[0]:
                 try:
@@ -1668,7 +1671,7 @@
             except KeyError:
                 pass
         rel = (variable.stinfo.get('principal') or
-               iter(variable.stinfo['rhsrelations']).next())
+               next(iter(variable.stinfo['rhsrelations'])))
         linkedvar = rel.children[0].variable
         if rel.r_type == 'eid':
             return linkedvar.accept(self)
--- a/server/sources/storages.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/sources/storages.py	Thu Dec 10 12:34:15 2015 +0100
@@ -23,6 +23,10 @@
 from contextlib import contextmanager
 import tempfile
 
+from six import PY2, PY3, text_type, binary_type
+
+from logilab.common import nullobject
+
 from yams.schema import role_name
 
 from cubicweb import Binary, ValidationError
@@ -44,7 +48,7 @@
       query result process of fetched attribute's value and should have the
       following prototype::
 
-        callback(self, source, session, value)
+        callback(self, source, cnx, value)
 
       where `value` is the value actually stored in the backend. None values
       will be skipped (eg callback won't be called).
@@ -92,24 +96,33 @@
     return tempfile.mkstemp(prefix=base, suffix=ext, dir=dirpath)
 
 @contextmanager
-def fsimport(session):
-    present = 'fs_importing' in session.transaction_data
-    old_value = session.transaction_data.get('fs_importing')
-    session.transaction_data['fs_importing'] = True
+def fsimport(cnx):
+    present = 'fs_importing' in cnx.transaction_data
+    old_value = cnx.transaction_data.get('fs_importing')
+    cnx.transaction_data['fs_importing'] = True
     yield
     if present:
-        session.transaction_data['fs_importing'] = old_value
+        cnx.transaction_data['fs_importing'] = old_value
     else:
-        del session.transaction_data['fs_importing']
+        del cnx.transaction_data['fs_importing']
+
+
+_marker = nullobject()
 
 
 class BytesFileSystemStorage(Storage):
     """store Bytes attribute value on the file system"""
-    def __init__(self, defaultdir, fsencoding='utf-8', wmode=0444):
-        if type(defaultdir) is unicode:
-            defaultdir = defaultdir.encode(fsencoding)
+    def __init__(self, defaultdir, fsencoding=_marker, wmode=0o444):
+        if PY3:
+            if not isinstance(defaultdir, text_type):
+                raise TypeError('defaultdir must be a unicode object in python 3')
+            if fsencoding is not _marker:
+                raise ValueError('fsencoding is no longer supported in python 3')
+        else:
+            self.fsencoding = fsencoding or 'utf-8'
+            if isinstance(defaultdir, text_type):
+                defaultdir = defaultdir.encode(fsencoding)
         self.default_directory = defaultdir
-        self.fsencoding = fsencoding
         # extra umask to use when creating file
         # 0444 as in "only allow read bit in permission"
         self._wmode = wmode
@@ -126,7 +139,7 @@
         fileobj.close()
 
 
-    def callback(self, source, session, value):
+    def callback(self, source, cnx, value):
         """sql generator callback when some attribute with a custom storage is
         accessed
         """
@@ -145,7 +158,8 @@
             binary = entity.cw_edited.pop(attr)
             fd, fpath = self.new_fs_path(entity, attr)
             # bytes storage used to store file's path
-            entity.cw_edited.edited_attribute(attr, Binary(fpath))
+            binary_obj = Binary(fpath if PY2 else fpath.encode('utf-8'))
+            entity.cw_edited.edited_attribute(attr, binary_obj)
             self._writecontent(fd, binary)
             AddFileOp.get_instance(entity._cw).add_data(fpath)
         return binary
@@ -187,7 +201,8 @@
                 entity.cw_edited.edited_attribute(attr, None)
             else:
                 # register the new location for the file.
-                entity.cw_edited.edited_attribute(attr, Binary(fpath))
+                binary_obj = Binary(fpath if PY2 else fpath.encode('utf-8'))
+                entity.cw_edited.edited_attribute(attr, binary_obj)
         if oldpath is not None and oldpath != fpath:
             # Mark the old file as useless so the file will be removed at
             # commit.
@@ -206,16 +221,19 @@
         # available. Keeping the extension is useful for example in the case of
         # PIL processing that use filename extension to detect content-type, as
         # well as providing more understandable file names on the fs.
+        if PY2:
+            attr = attr.encode('ascii')
         basename = [str(entity.eid), attr]
         name = entity.cw_attr_metadata(attr, 'name')
         if name is not None:
-            basename.append(name.encode(self.fsencoding))
+            basename.append(name.encode(self.fsencoding) if PY2 else name)
         fd, fspath = uniquify_path(self.default_directory,
                                '_'.join(basename))
         if fspath is None:
             msg = entity._cw._('failed to uniquify path (%s, %s)') % (
                 self.default_directory, '_'.join(basename))
             raise ValidationError(entity.eid, {role_name(attr, 'subject'): msg})
+        assert isinstance(fspath, str)  # bytes on py2, unicode on py3
         return fd, fspath
 
     def current_fs_path(self, entity, attr):
@@ -229,34 +247,40 @@
         rawvalue = cu.fetchone()[0]
         if rawvalue is None: # no previous value
             return None
-        return sysource._process_value(rawvalue, cu.description[0],
-                                       binarywrap=str)
+        fspath = sysource._process_value(rawvalue, cu.description[0],
+                                         binarywrap=binary_type)
+        if PY3:
+            fspath = fspath.decode('utf-8')
+        assert isinstance(fspath, str)  # bytes on py2, unicode on py3
+        return fspath
 
     def migrate_entity(self, entity, attribute):
         """migrate an entity attribute to the storage"""
         entity.cw_edited = EditedEntity(entity, **entity.cw_attr_cache)
         self.entity_added(entity, attribute)
-        session = entity._cw
-        source = session.repo.system_source
+        cnx = entity._cw
+        source = cnx.repo.system_source
         attrs = source.preprocess_entity(entity)
         sql = source.sqlgen.update('cw_' + entity.cw_etype, attrs,
                                    ['cw_eid'])
-        source.doexec(session, sql, attrs)
+        source.doexec(cnx, sql, attrs)
         entity.cw_edited = None
 
 
 class AddFileOp(hook.DataOperationMixIn, hook.Operation):
     def rollback_event(self):
         for filepath in self.get_data():
+            assert isinstance(filepath, str)  # bytes on py2, unicode on py3
             try:
                 unlink(filepath)
             except Exception as ex:
-                self.error('cant remove %s: %s' % (filepath, ex))
+                self.error("can't remove %s: %s" % (filepath, ex))
 
 class DeleteFileOp(hook.DataOperationMixIn, hook.Operation):
     def postcommit_event(self):
         for filepath in self.get_data():
+            assert isinstance(filepath, str)  # bytes on py2, unicode on py3
             try:
                 unlink(filepath)
             except Exception as ex:
-                self.error('cant remove %s: %s' % (filepath, ex))
+                self.error("can't remove %s: %s" % (filepath, ex))
--- a/server/sqlutils.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/sqlutils.py	Thu Dec 10 12:34:15 2015 +0100
@@ -16,6 +16,7 @@
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """SQL utilities functions and classes."""
+from __future__ import print_function
 
 __docformat__ = "restructuredtext en"
 
@@ -23,10 +24,12 @@
 import re
 import subprocess
 from os.path import abspath
-from itertools import ifilter
 from logging import getLogger
 from datetime import time, datetime
 
+from six import string_types, text_type
+from six.moves import filter
+
 from logilab import database as db, common as lgc
 from logilab.common.shellutils import ProgressBar, DummyProgressBar
 from logilab.common.deprecation import deprecated
@@ -44,8 +47,12 @@
 SQL_PREFIX = 'cw_'
 
 def _run_command(cmd):
-    print ' '.join(cmd)
-    return subprocess.call(cmd)
+    if isinstance(cmd, string_types):
+        print(cmd)
+        return subprocess.call(cmd, shell=True)
+    else:
+        print(' '.join(cmd))
+        return subprocess.call(cmd)
 
 
 def sqlexec(sqlstmts, cursor_or_execute, withpb=True,
@@ -69,7 +76,7 @@
     else:
         execute = cursor_or_execute
     sqlstmts_as_string = False
-    if isinstance(sqlstmts, basestring):
+    if isinstance(sqlstmts, string_types):
         sqlstmts_as_string = True
         sqlstmts = sqlstmts.split(delimiter)
     if withpb:
@@ -87,7 +94,7 @@
         try:
             # some dbapi modules doesn't accept unicode for sql string
             execute(str(sql))
-        except Exception, err:
+        except Exception as err:
             if cnx:
                 cnx.rollback()
             failed.append(sql)
@@ -95,7 +102,7 @@
             if cnx:
                 cnx.commit()
     if withpb:
-        print
+        print()
     if sqlstmts_as_string:
         failed = delimiter.join(failed)
     return failed
@@ -178,9 +185,9 @@
     # for mssql, we need to drop views before tables
     if hasattr(dbhelper, 'list_views'):
         cmds += ['DROP VIEW %s;' % name
-                 for name in ifilter(_SQL_DROP_ALL_USER_TABLES_FILTER_FUNCTION, dbhelper.list_views(sqlcursor))]
+                 for name in filter(_SQL_DROP_ALL_USER_TABLES_FILTER_FUNCTION, dbhelper.list_views(sqlcursor))]
     cmds += ['DROP TABLE %s;' % name
-             for name in ifilter(_SQL_DROP_ALL_USER_TABLES_FILTER_FUNCTION, dbhelper.list_tables(sqlcursor))]
+             for name in filter(_SQL_DROP_ALL_USER_TABLES_FILTER_FUNCTION, dbhelper.list_tables(sqlcursor))]
     return '\n'.join(cmds)
 
 
@@ -370,7 +377,7 @@
     def merge_args(self, args, query_args):
         if args is not None:
             newargs = {}
-            for key, val in args.iteritems():
+            for key, val in args.items():
                 # convert cubicweb binary into db binary
                 if isinstance(val, Binary):
                     val = self._binary(val.getvalue())
@@ -441,7 +448,7 @@
         attrs = {}
         eschema = entity.e_schema
         converters = getattr(self.dbhelper, 'TYPE_CONVERTERS', {})
-        for attr, value in entity.cw_edited.iteritems():
+        for attr, value in entity.cw_edited.items():
             if value is not None and eschema.subjrels[attr].final:
                 atype = str(entity.e_schema.destination(attr))
                 if atype in converters:
@@ -481,7 +488,7 @@
             if value is not None:
                 self.values.add(value)
         def finalize(self):
-            return ', '.join(unicode(v) for v in self.values)
+            return ', '.join(text_type(v) for v in self.values)
 
     cnx.create_aggregate("GROUP_CONCAT", 1, group_concat)
 
--- a/server/ssplanner.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/ssplanner.py	Thu Dec 10 12:34:15 2015 +0100
@@ -19,6 +19,8 @@
 
 __docformat__ = "restructuredtext en"
 
+from six import text_type
+
 from rql.stmts import Union, Select
 from rql.nodes import Constant, Relation
 
@@ -54,7 +56,7 @@
                 value = rhs.eval(plan.args)
                 eschema = edef.entity.e_schema
                 attrtype = eschema.subjrels[rtype].objects(eschema)[0]
-                if attrtype == 'Password' and isinstance(value, unicode):
+                if attrtype == 'Password' and isinstance(value, text_type):
                     value = value.encode('UTF8')
                 edef.edited_attribute(rtype, value)
             elif str(rhs) in to_build:
@@ -306,7 +308,7 @@
     if varmap is None:
         return varmap
     maprepr = {}
-    for var, sql in varmap.iteritems():
+    for var, sql in varmap.items():
         table, col = sql.split('.')
         maprepr[var] = '%s.%s' % (tablesinorder[table], col)
     return maprepr
@@ -527,7 +529,7 @@
             result[i] = newrow
         # update entities
         repo.glob_add_relations(cnx, relations)
-        for eid, edited in edefs.iteritems():
+        for eid, edited in edefs.items():
             repo.glob_update_entity(cnx, edited)
         return result
 
--- a/server/test/data-cwep002/schema.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/test/data-cwep002/schema.py	Thu Dec 10 12:34:15 2015 +0100
@@ -33,4 +33,3 @@
 class has_employee(ComputedRelation):
     rule = 'O works_for S'
     __permissions__ = {'read': ('managers',)}
-
--- a/server/test/data-migractions/cubes/fakeemail/schema.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/test/data-migractions/cubes/fakeemail/schema.py	Thu Dec 10 12:34:15 2015 +0100
@@ -5,7 +5,7 @@
 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
 """
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 # pylint: disable-msg=E0611,F0401
 from yams.buildobjs import (SubjectRelation, RelationType, EntityType,
@@ -84,5 +84,3 @@
         subject = 'Comment'
         name = 'generated_by'
         object = 'Email'
-
-
--- a/server/test/data-migractions/migratedapp/schema.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/test/data-migractions/migratedapp/schema.py	Thu Dec 10 12:34:15 2015 +0100
@@ -21,6 +21,7 @@
                             SubjectRelation, Bytes,
                             RichString, String, Int, Boolean, Datetime, Date, Float)
 from yams.constraints import SizeConstraint, UniqueConstraint
+from cubicweb import _
 from cubicweb.schema import (WorkflowableEntityType, RQLConstraint,
                              RQLVocabularyConstraint,
                              ERQLExpression, RRQLExpression)
--- a/server/test/data-migractions/schema.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/test/data-migractions/schema.py	Thu Dec 10 12:34:15 2015 +0100
@@ -24,6 +24,8 @@
                              RQLConstraint, RQLUniqueConstraint,
                              RQLVocabularyConstraint,
                              ERQLExpression, RRQLExpression)
+from cubicweb import _
+
 
 class Affaire(WorkflowableEntityType):
     __permissions__ = {
@@ -85,7 +87,7 @@
     object = 'SubDivision'
 
 from cubicweb.schemas.base import CWUser
-CWUser.get_relations('login').next().fulltextindexed = True
+next(CWUser.get_relations('login')).fulltextindexed = True
 
 class Note(WorkflowableEntityType):
     date = String(maxsize=10)
@@ -223,13 +225,13 @@
 class ecrit_par_1(RelationDefinition):
     name = 'ecrit_par'
     subject = 'Note'
-    object ='Personne'
+    object = 'Personne'
     cardinality = '?*'
 
 class ecrit_par_2(RelationDefinition):
     name = 'ecrit_par'
     subject = 'Note'
-    object ='CWUser'
+    object = 'CWUser'
     cardinality='?*'
 
 
--- a/server/test/data-schema2sql/schema/Dates.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/test/data-schema2sql/schema/Dates.py	Thu Dec 10 12:34:15 2015 +0100
@@ -26,4 +26,3 @@
     d2  = Date(default=date(2007, 12, 11))
     t1  = Time(default=time(8, 40))
     t2  = Time(default=time(9, 45))
-
--- a/server/test/data-schema2sql/schema/State.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/test/data-schema2sql/schema/State.py	Thu Dec 10 12:34:15 2015 +0100
@@ -19,7 +19,7 @@
                             SubjectRelation, Int, String,  Boolean)
 from yams.constraints import SizeConstraint, UniqueConstraint
 
-from __init__ import RESTRICTED_RTYPE_PERMS
+from . import RESTRICTED_RTYPE_PERMS
 
 class State(EntityType):
     """used to associate simple states to an entity
--- a/server/test/data-schema2sql/schema/schema.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/test/data-schema2sql/schema/schema.py	Thu Dec 10 12:34:15 2015 +0100
@@ -110,4 +110,3 @@
         'add': ('managers',),
         'delete': ('managers',),
         }
-
--- a/server/test/data-schemaserial/schema.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/test/data-schemaserial/schema.py	Thu Dec 10 12:34:15 2015 +0100
@@ -29,4 +29,3 @@
     inline2 = SubjectRelation('Affaire', inlined=True, cardinality='?*')
 
     custom_field_of_jungle = BabarTestType(jungle_speed=42)
-
--- a/server/test/data-schemaserial/site_cubicweb.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/test/data-schemaserial/site_cubicweb.py	Thu Dec 10 12:34:15 2015 +0100
@@ -27,4 +27,3 @@
 def dumb_sort(something):
     return something
 register_sqlite_pyfunc(dumb_sort)
-
--- a/server/test/data/migration/postcreate.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/test/data/migration/postcreate.py	Thu Dec 10 12:34:15 2015 +0100
@@ -35,4 +35,3 @@
 wf.add_transition(u'start', pitetre, encours)
 wf.add_transition(u'end', encours, finie)
 commit()
-
--- a/server/test/data/schema.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/test/data/schema.py	Thu Dec 10 12:34:15 2015 +0100
@@ -24,6 +24,7 @@
                              RQLConstraint, RQLUniqueConstraint,
                              RQLVocabularyConstraint,
                              ERQLExpression, RRQLExpression)
+from cubicweb import _
 
 class Affaire(WorkflowableEntityType):
     __permissions__ = {
@@ -85,7 +86,7 @@
     object = 'SubDivision'
 
 from cubicweb.schemas.base import CWUser
-CWUser.get_relations('login').next().fulltextindexed = True
+next(CWUser.get_relations('login')).fulltextindexed = True
 
 class Note(WorkflowableEntityType):
     date = String(maxsize=10)
--- a/server/test/datacomputed/migratedapp/schema.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/test/datacomputed/migratedapp/schema.py	Thu Dec 10 12:34:15 2015 +0100
@@ -59,3 +59,8 @@
 
 class renamed(ComputedRelation):
     rule = 'S employees E, O concerns E'
+
+
+class perm_changes(ComputedRelation):
+    __permissions__ = {'read': ('managers',)}
+    rule = 'S employees E, O concerns E'
--- a/server/test/datacomputed/schema.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/test/datacomputed/schema.py	Thu Dec 10 12:34:15 2015 +0100
@@ -58,3 +58,8 @@
 
 class to_be_renamed(ComputedRelation):
     rule = 'S employees E, O concerns E'
+
+
+class perm_changes(ComputedRelation):
+    __permissions__ = {'read': ('managers', 'users')}
+    rule = 'S employees E, O concerns E'
--- a/server/test/requirements.txt	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/test/requirements.txt	Thu Dec 10 12:34:15 2015 +0100
@@ -1,4 +1,5 @@
 psycopg2
+ldap3
 cubicweb-basket
 cubicweb-card
 cubicweb-comment
--- a/server/test/unittest_checkintegrity.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/test/unittest_checkintegrity.py	Thu Dec 10 12:34:15 2015 +0100
@@ -17,7 +17,13 @@
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 
 import sys
-from StringIO import StringIO
+
+from six import PY2
+if PY2:
+    from StringIO import StringIO
+else:
+    from io import StringIO
+
 from logilab.common.testlib import TestCase, unittest_main
 from cubicweb.devtools import get_test_db_handler, TestServerConfiguration
 
--- a/server/test/unittest_datafeed.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/test/unittest_datafeed.py	Thu Dec 10 12:34:15 2015 +0100
@@ -1,3 +1,4 @@
+# coding: utf-8
 # copyright 2011-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
@@ -16,7 +17,6 @@
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 
-import mimetools
 from datetime import timedelta
 from contextlib import contextmanager
 
@@ -28,7 +28,7 @@
     def setup_database(self):
         with self.admin_access.repo_cnx() as cnx:
             with self.base_parser(cnx):
-                cnx.create_entity('CWSource', name=u'myfeed', type=u'datafeed',
+                cnx.create_entity('CWSource', name=u'ô myfeed', type=u'datafeed',
                                   parser=u'testparser', url=u'ignored',
                                   config=u'synchronization-interval=1min')
                 cnx.commit()
@@ -48,21 +48,23 @@
                 entity.cw_edited.update(sourceparams['item'])
 
         with self.temporary_appobjects(AParser):
-            if 'myfeed' in self.repo.sources_by_uri:
-                yield self.repo.sources_by_uri['myfeed']._get_parser(session)
+            if u'ô myfeed' in self.repo.sources_by_uri:
+                yield self.repo.sources_by_uri[u'ô myfeed']._get_parser(session)
             else:
                 yield
 
     def test(self):
-        self.assertIn('myfeed', self.repo.sources_by_uri)
-        dfsource = self.repo.sources_by_uri['myfeed']
+        self.assertIn(u'ô myfeed', self.repo.sources_by_uri)
+        dfsource = self.repo.sources_by_uri[u'ô myfeed']
         self.assertNotIn('use_cwuri_as_url', dfsource.__dict__)
-        self.assertEqual({'type': u'datafeed', 'uri': u'myfeed', 'use-cwuri-as-url': True},
+        self.assertEqual({'type': u'datafeed', 'uri': u'ô myfeed', 'use-cwuri-as-url': True},
                          dfsource.public_config)
         self.assertEqual(dfsource.use_cwuri_as_url, True)
         self.assertEqual(dfsource.latest_retrieval, None)
         self.assertEqual(dfsource.synchro_interval, timedelta(seconds=60))
         self.assertFalse(dfsource.fresh())
+        # ensure source's logger name has been unormalized
+        self.assertEqual(dfsource.info.__self__.name, 'cubicweb.sources.o myfeed')
 
         with self.repo.internal_cnx() as cnx:
             with self.base_parser(cnx):
@@ -78,17 +80,17 @@
                 self.assertEqual(entity.title, 'cubicweb.org')
                 self.assertEqual(entity.content, 'the cw web site')
                 self.assertEqual(entity.cwuri, 'http://www.cubicweb.org/')
-                self.assertEqual(entity.cw_source[0].name, 'myfeed')
+                self.assertEqual(entity.cw_source[0].name, u'ô myfeed')
                 self.assertEqual(entity.cw_metainformation(),
                                  {'type': 'Card',
-                                  'source': {'uri': 'myfeed', 'type': 'datafeed', 'use-cwuri-as-url': True},
-                                  'extid': 'http://www.cubicweb.org/'}
+                                  'source': {'uri': u'ô myfeed', 'type': 'datafeed', 'use-cwuri-as-url': True},
+                                  'extid': b'http://www.cubicweb.org/'}
                                  )
                 self.assertEqual(entity.absolute_url(), 'http://www.cubicweb.org/')
                 # test repo cache keys
                 self.assertEqual(self.repo._type_source_cache[entity.eid],
-                                 ('Card', 'http://www.cubicweb.org/', 'myfeed'))
-                self.assertEqual(self.repo._extid_cache['http://www.cubicweb.org/'],
+                                 ('Card', b'http://www.cubicweb.org/', u'ô myfeed'))
+                self.assertEqual(self.repo._extid_cache[b'http://www.cubicweb.org/'],
                                  entity.eid)
                 # test repull
                 stats = dfsource.pull_data(cnx, force=True)
@@ -101,19 +103,18 @@
                 self.assertEqual(stats['created'], set())
                 self.assertEqual(stats['updated'], set((entity.eid,)))
                 self.assertEqual(self.repo._type_source_cache[entity.eid],
-                                 ('Card', 'http://www.cubicweb.org/', 'myfeed'))
-                self.assertEqual(self.repo._extid_cache['http://www.cubicweb.org/'],
+                                 ('Card', b'http://www.cubicweb.org/', u'ô myfeed'))
+                self.assertEqual(self.repo._extid_cache[b'http://www.cubicweb.org/'],
                                  entity.eid)
 
                 self.assertEqual(dfsource.source_cwuris(cnx),
-                                 {'http://www.cubicweb.org/': (entity.eid, 'Card')}
-                             )
+                                 {b'http://www.cubicweb.org/': (entity.eid, 'Card')})
                 self.assertTrue(dfsource.latest_retrieval)
                 self.assertTrue(dfsource.fresh())
 
         # test_rename_source
         with self.admin_access.repo_cnx() as cnx:
-            cnx.execute('SET S name "myrenamedfeed" WHERE S is CWSource, S name "myfeed"')
+            cnx.entity_from_eid(dfsource.eid).cw_set(name=u"myrenamedfeed")
             cnx.commit()
             entity = cnx.execute('Card X').get_entity(0, 0)
             self.assertEqual(entity.cwuri, 'http://www.cubicweb.org/')
@@ -121,11 +122,11 @@
             self.assertEqual(entity.cw_metainformation(),
                              {'type': 'Card',
                               'source': {'uri': 'myrenamedfeed', 'type': 'datafeed', 'use-cwuri-as-url': True},
-                              'extid': 'http://www.cubicweb.org/'}
+                              'extid': b'http://www.cubicweb.org/'}
                              )
             self.assertEqual(self.repo._type_source_cache[entity.eid],
-                             ('Card', 'http://www.cubicweb.org/', 'myrenamedfeed'))
-            self.assertEqual(self.repo._extid_cache['http://www.cubicweb.org/'],
+                             ('Card', b'http://www.cubicweb.org/', 'myrenamedfeed'))
+            self.assertEqual(self.repo._extid_cache[b'http://www.cubicweb.org/'],
                              entity.eid)
 
             # test_delete_source
@@ -140,7 +141,14 @@
                 value = parser.retrieve_url('a string')
                 self.assertEqual(200, value.getcode())
                 self.assertEqual('a string', value.geturl())
-                self.assertIsInstance(value.info(), mimetools.Message)
+
+    def test_update_url(self):
+        dfsource = self.repo.sources_by_uri[u'ô myfeed']
+        with self.admin_access.repo_cnx() as cnx:
+            cnx.entity_from_eid(dfsource.eid).cw_set(url=u"http://pouet.com\nhttp://pouet.org")
+            self.assertEqual(dfsource.urls, [u'ignored'])
+            cnx.commit()
+        self.assertEqual(dfsource.urls, [u"http://pouet.com", u"http://pouet.org"])
 
 
 class DataFeedConfigTC(CubicWebTC):
--- a/server/test/unittest_ldapsource.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/test/unittest_ldapsource.py	Thu Dec 10 12:34:15 2015 +0100
@@ -15,19 +15,26 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
-"""cubicweb.server.sources.ldapusers unit and functional tests"""
+"""cubicweb.server.sources.ldapfeed unit and functional tests
+
+Those tests expect to have slapd, python-ldap3 and ldapscripts packages installed.
+"""
+from __future__ import print_function
 
 import os
 import sys
 import shutil
 import time
-from os.path import join, exists
 import subprocess
 import tempfile
+import unittest
+from os.path import join
+
+from six import string_types
+from six.moves import range
 
 from cubicweb import AuthenticationError
 from cubicweb.devtools.testlib import CubicWebTC
-from cubicweb.devtools.repotest import RQLGeneratorTC
 from cubicweb.devtools.httptest import get_available_port
 
 
@@ -44,13 +51,14 @@
 
 URL = None
 
+
 def create_slapd_configuration(cls):
     global URL
     slapddir = tempfile.mkdtemp('cw-unittest-ldap')
     config = cls.config
     slapdconf = join(config.apphome, "slapd.conf")
-    confin = file(join(config.apphome, "slapd.conf.in")).read()
-    confstream = file(slapdconf, 'w')
+    confin = open(join(config.apphome, "slapd.conf.in")).read()
+    confstream = open(slapdconf, 'w')
     confstream.write(confin % {'apphome': config.apphome, 'testdir': slapddir})
     confstream.close()
     # fill ldap server with some data
@@ -61,16 +69,16 @@
     slapproc = subprocess.Popen(cmdline, stdout=PIPE, stderr=PIPE)
     stdout, stderr = slapproc.communicate()
     if slapproc.returncode:
-        print >> sys.stderr, ('slapadd returned with status: %s'
-                              % slapproc.returncode)
+        print('slapadd returned with status: %s'
+              % slapproc.returncode, file=sys.stderr)
         sys.stdout.write(stdout)
         sys.stderr.write(stderr)
 
-    #ldapuri = 'ldapi://' + join(basedir, "ldapi").replace('/', '%2f')
-    port = get_available_port(xrange(9000, 9100))
+    # ldapuri = 'ldapi://' + join(basedir, "ldapi").replace('/', '%2f')
+    port = get_available_port(range(9000, 9100))
     host = 'localhost:%s' % port
     ldapuri = 'ldap://%s' % host
-    cmdline = ["/usr/sbin/slapd", "-f",  slapdconf,  "-h",  ldapuri, "-d", "0"]
+    cmdline = ["/usr/sbin/slapd", "-f", slapdconf, "-h", ldapuri, "-d", "0"]
     config.info('Starting slapd:', ' '.join(cmdline))
     PIPE = subprocess.PIPE
     cls.slapd_process = subprocess.Popen(cmdline, stdout=PIPE, stderr=PIPE)
@@ -83,6 +91,7 @@
     URL = u'ldap://%s' % host
     return slapddir
 
+
 def terminate_slapd(cls):
     config = cls.config
     if cls.slapd_process and cls.slapd_process.returncode is None:
@@ -90,12 +99,12 @@
         if hasattr(cls.slapd_process, 'terminate'):
             cls.slapd_process.terminate()
         else:
-            import os, signal
+            import signal
             os.kill(cls.slapd_process.pid, signal.SIGTERM)
         stdout, stderr = cls.slapd_process.communicate()
         if cls.slapd_process.returncode:
-            print >> sys.stderr, ('slapd returned with status: %s'
-                                  % cls.slapd_process.returncode)
+            print('slapd returned with status: %s'
+                  % cls.slapd_process.returncode, file=sys.stderr)
             sys.stdout.write(stdout)
             sys.stderr.write(stderr)
         config.info('DONE')
@@ -107,6 +116,8 @@
 
     @classmethod
     def setUpClass(cls):
+        if not os.path.exists('/usr/sbin/slapd'):
+            raise unittest.SkipTest('slapd not found')
         from cubicweb.cwctl import init_cmdline_log_threshold
         init_cmdline_log_threshold(cls.config, cls.loglevel)
         cls._tmpdir = create_slapd_configuration(cls)
@@ -139,7 +150,7 @@
             cnx.execute('DELETE Any E WHERE E cw_source S, S name "ldap"')
             cnx.execute('SET S config %(conf)s, S url %(url)s '
                         'WHERE S is CWSource, S name "ldap"',
-                        {"conf": CONFIG_LDAPFEED, 'url': URL} )
+                        {"conf": CONFIG_LDAPFEED, 'url': URL})
             cnx.commit()
         with self.repo.internal_cnx() as cnx:
             self.pull(cnx)
@@ -148,32 +159,32 @@
         """
         add an LDAP entity
         """
-        modcmd = ['dn: %s'%dn, 'changetype: add']
-        for key, values in mods.iteritems():
-            if isinstance(values, basestring):
+        modcmd = ['dn: %s' % dn, 'changetype: add']
+        for key, values in mods.items():
+            if isinstance(values, string_types):
                 values = [values]
             for value in values:
-                modcmd.append('%s: %s'%(key, value))
+                modcmd.append('%s: %s' % (key, value))
         self._ldapmodify(modcmd)
 
     def delete_ldap_entry(self, dn):
         """
         delete an LDAP entity
         """
-        modcmd = ['dn: %s'%dn, 'changetype: delete']
+        modcmd = ['dn: %s' % dn, 'changetype: delete']
         self._ldapmodify(modcmd)
 
     def update_ldap_entry(self, dn, mods):
         """
         modify one or more attributes of an LDAP entity
         """
-        modcmd = ['dn: %s'%dn, 'changetype: modify']
-        for (kind, key), values in mods.iteritems():
+        modcmd = ['dn: %s' % dn, 'changetype: modify']
+        for (kind, key), values in mods.items():
             modcmd.append('%s: %s' % (kind, key))
-            if isinstance(values, basestring):
+            if isinstance(values, string_types):
                 values = [values]
             for value in values:
-                modcmd.append('%s: %s'%(key, value))
+                modcmd.append('%s: %s' % (key, value))
             modcmd.append('-')
         self._ldapmodify(modcmd)
 
@@ -183,10 +194,11 @@
                      'cn=admin,dc=cubicweb,dc=test', '-w', 'cw']
         PIPE = subprocess.PIPE
         p = subprocess.Popen(updatecmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
-        p.stdin.write('\n'.join(modcmd))
+        p.stdin.write('\n'.join(modcmd).encode('ascii'))
         p.stdin.close()
         if p.wait():
-            raise RuntimeError("ldap update failed: %s"%('\n'.join(p.stderr.readlines())))
+            raise RuntimeError("ldap update failed: %s" % ('\n'.join(p.stderr.readlines())))
+
 
 class CheckWrongGroup(LDAPFeedTestBase):
     """
@@ -196,18 +208,17 @@
 
     def test_wrong_group(self):
         with self.admin_access.repo_cnx() as cnx:
-            source = cnx.execute('CWSource S WHERE S type="ldapfeed"').get_entity(0,0)
+            source = cnx.execute('CWSource S WHERE S type="ldapfeed"').get_entity(0, 0)
             config = source.repo_source.check_config(source)
             # inject a bogus group here, along with at least a valid one
-            config['user-default-group'] = ('thisgroupdoesnotexists','users')
+            config['user-default-group'] = ('thisgroupdoesnotexists', 'users')
             source.repo_source.update_config(source, config)
             cnx.commit()
             # here we emitted an error log entry
-            stats = source.repo_source.pull_data(cnx, force=True, raise_on_error=True)
+            source.repo_source.pull_data(cnx, force=True, raise_on_error=True)
             cnx.commit()
 
 
-
 class LDAPFeedUserTC(LDAPFeedTestBase):
     """
     A testcase for CWUser support in ldapfeed (basic tests and authentication).
@@ -284,12 +295,12 @@
             # and that the password stored in the system source is not empty or so
             user = cnx.execute('CWUser U WHERE U login "syt"').get_entity(0, 0)
             user.cw_clear_all_caches()
-            pwd = cnx.system_sql("SELECT cw_upassword FROM cw_cwuser WHERE cw_login='syt';").fetchall()[0][0]
+            cu = cnx.system_sql("SELECT cw_upassword FROM cw_cwuser WHERE cw_login='syt';")
+            pwd = cu.fetchall()[0][0]
             self.assertIsNotNone(pwd)
             self.assertTrue(str(pwd))
 
 
-
 class LDAPFeedUserDeletionTC(LDAPFeedTestBase):
     """
     A testcase for situations where users are deleted from or
@@ -299,7 +310,7 @@
     def test_a_filter_inactivate(self):
         """ filtered out people should be deactivated, unable to authenticate """
         with self.admin_access.repo_cnx() as cnx:
-            source = cnx.execute('CWSource S WHERE S type="ldapfeed"').get_entity(0,0)
+            source = cnx.execute('CWSource S WHERE S type="ldapfeed"').get_entity(0, 0)
             config = source.repo_source.check_config(source)
             # filter with adim's phone number
             config['user-filter'] = u'(%s=%s)' % ('telephoneNumber', '109')
@@ -346,21 +357,22 @@
             self.pull(cnx)
         # reinsert syt
         self.add_ldap_entry('uid=syt,ou=People,dc=cubicweb,dc=test',
-                            { 'objectClass': ['OpenLDAPperson','posixAccount','top','shadowAccount'],
-                              'cn': 'Sylvain Thenault',
-                              'sn': 'Thenault',
-                              'gidNumber': '1004',
-                              'uid': 'syt',
-                              'homeDirectory': '/home/syt',
-                              'shadowFlag': '134538764',
-                              'uidNumber': '1004',
-                              'givenName': 'Sylvain',
-                              'telephoneNumber': '106',
-                              'displayName': 'sthenault',
-                              'gecos': 'Sylvain Thenault',
-                              'mail': ['sylvain.thenault@logilab.fr','syt@logilab.fr'],
-                              'userPassword': 'syt',
-                          })
+                            {'objectClass': ['OpenLDAPperson', 'posixAccount', 'top',
+                                             'shadowAccount'],
+                             'cn': 'Sylvain Thenault',
+                             'sn': 'Thenault',
+                             'gidNumber': '1004',
+                             'uid': 'syt',
+                             'homeDirectory': '/home/syt',
+                             'shadowFlag': '134538764',
+                             'uidNumber': '1004',
+                             'givenName': 'Sylvain',
+                             'telephoneNumber': '106',
+                             'displayName': 'sthenault',
+                             'gecos': 'Sylvain Thenault',
+                             'mail': ['sylvain.thenault@logilab.fr', 'syt@logilab.fr'],
+                             'userPassword': 'syt',
+                             })
         with self.repo.internal_cnx() as cnx:
             self.pull(cnx)
         with self.admin_access.repo_cnx() as cnx:
@@ -433,8 +445,7 @@
 
         try:
             self.update_ldap_entry('cn=logilab,ou=Group,dc=cubicweb,dc=test',
-                                       {('add', 'memberUid'): ['syt']})
-            time.sleep(1.1) # timestamps precision is 1s
+                                   {('add', 'memberUid'): ['syt']})
             with self.repo.internal_cnx() as cnx:
                 self.pull(cnx)
 
@@ -452,7 +463,7 @@
 
     def test_group_member_deleted(self):
         with self.repo.internal_cnx() as cnx:
-            self.pull(cnx) # ensure we are sync'ed
+            self.pull(cnx)  # ensure we are sync'ed
         with self.admin_access.repo_cnx() as cnx:
             rset = cnx.execute('Any L WHERE U in_group G, G name %(name)s, U login L',
                                {'name': 'logilab'})
@@ -462,21 +473,19 @@
         try:
             self.update_ldap_entry('cn=logilab,ou=Group,dc=cubicweb,dc=test',
                                    {('delete', 'memberUid'): ['adim']})
-            time.sleep(1.1) # timestamps precision is 1s
             with self.repo.internal_cnx() as cnx:
                 self.pull(cnx)
 
             with self.admin_access.repo_cnx() as cnx:
                 rset = cnx.execute('Any L WHERE U in_group G, G name %(name)s, U login L',
                                    {'name': 'logilab'})
-                self.assertEqual(len(rset), 0)
+                self.assertEqual(len(rset), 0, rset.rows)
         finally:
             # back to normal ldap setup
             self.tearDownClass()
             self.setUpClass()
 
 
-
 if __name__ == '__main__':
     from logilab.common.testlib import unittest_main
     unittest_main()
--- a/server/test/unittest_migractions.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/test/unittest_migractions.py	Thu Dec 10 12:34:15 2015 +0100
@@ -22,6 +22,7 @@
 from contextlib import contextmanager
 
 from logilab.common.testlib import unittest_main, Tags, tag
+from logilab.common import tempattr
 
 from yams.constraints import UniqueConstraint
 
@@ -54,7 +55,8 @@
 
 class MigrationConfig(cubicweb.devtools.TestServerConfiguration):
     default_sources = cubicweb.devtools.DEFAULT_PSQL_SOURCES
-    CUBES_PATH = [osp.join(HERE, 'data-migractions', 'cubes')]
+    CUBES_PATH = cubicweb.devtools.TestServerConfiguration.CUBES_PATH + [
+        osp.join(HERE, 'data-migractions', 'cubes')]
 
 
 class MigrationTC(CubicWebTC):
@@ -151,7 +153,7 @@
             orderdict2 = dict(mh.rqlexec('Any RTN, O WHERE X name "Note", RDEF from_entity X, '
                                          'RDEF relation_type RT, RDEF ordernum O, RT name RTN'))
             whateverorder = migrschema['whatever'].rdef('Note', 'Int').order
-            for k, v in orderdict.iteritems():
+            for k, v in orderdict.items():
                 if v >= whateverorder:
                     orderdict[k] = v+1
             orderdict['whatever'] = whateverorder
@@ -524,12 +526,12 @@
             # remaining orphan rql expr which should be deleted at commit (composite relation)
             # unattached expressions -> pending deletion on commit
             self.assertEqual(cnx.execute('Any COUNT(X) WHERE X is RQLExpression, X exprtype "ERQLExpression",'
-                                            'NOT ET1 read_permission X, NOT ET2 add_permission X, '
-                                            'NOT ET3 delete_permission X, NOT ET4 update_permission X')[0][0],
+                                         'NOT ET1 read_permission X, NOT ET2 add_permission X, '
+                                         'NOT ET3 delete_permission X, NOT ET4 update_permission X')[0][0],
                               7)
             self.assertEqual(cnx.execute('Any COUNT(X) WHERE X is RQLExpression, X exprtype "RRQLExpression",'
-                                            'NOT ET1 read_permission X, NOT ET2 add_permission X, '
-                                            'NOT ET3 delete_permission X, NOT ET4 update_permission X')[0][0],
+                                         'NOT ET1 read_permission X, NOT ET2 add_permission X, '
+                                         'NOT ET3 delete_permission X, NOT ET4 update_permission X')[0][0],
                               2)
             # finally
             self.assertEqual(cnx.execute('Any COUNT(X) WHERE X is RQLExpression')[0][0],
@@ -579,7 +581,7 @@
     def test_add_drop_cube_and_deps(self):
         with self.mh() as (cnx, mh):
             schema = self.repo.schema
-            self.assertEqual(sorted((str(s), str(o)) for s, o in schema['see_also'].rdefs.iterkeys()),
+            self.assertEqual(sorted((str(s), str(o)) for s, o in schema['see_also'].rdefs),
                              sorted([('EmailThread', 'EmailThread'), ('Folder', 'Folder'),
                                      ('Bookmark', 'Bookmark'), ('Bookmark', 'Note'),
                                      ('Note', 'Note'), ('Note', 'Bookmark')]))
@@ -593,7 +595,7 @@
                 for ertype in ('Email', 'EmailThread', 'EmailPart', 'File',
                                'sender', 'in_thread', 'reply_to', 'data_format'):
                     self.assertNotIn(ertype, schema)
-                self.assertEqual(sorted(schema['see_also'].rdefs.iterkeys()),
+                self.assertEqual(sorted(schema['see_also'].rdefs),
                                   sorted([('Folder', 'Folder'),
                                           ('Bookmark', 'Bookmark'),
                                           ('Bookmark', 'Note'),
@@ -612,12 +614,12 @@
                 for ertype in ('Email', 'EmailThread', 'EmailPart', 'File',
                                'sender', 'in_thread', 'reply_to', 'data_format'):
                     self.assertIn(ertype, schema)
-                self.assertEqual(sorted(schema['see_also'].rdefs.iterkeys()),
-                                  sorted([('EmailThread', 'EmailThread'), ('Folder', 'Folder'),
-                                          ('Bookmark', 'Bookmark'),
-                                          ('Bookmark', 'Note'),
-                                          ('Note', 'Note'),
-                                          ('Note', 'Bookmark')]))
+                self.assertEqual(sorted(schema['see_also'].rdefs),
+                                 sorted([('EmailThread', 'EmailThread'), ('Folder', 'Folder'),
+                                         ('Bookmark', 'Bookmark'),
+                                         ('Bookmark', 'Note'),
+                                         ('Note', 'Note'),
+                                         ('Note', 'Bookmark')]))
                 self.assertEqual(sorted(schema['see_also'].subjects()), ['Bookmark', 'EmailThread', 'Folder', 'Note'])
                 self.assertEqual(sorted(schema['see_also'].objects()), ['Bookmark', 'EmailThread', 'Folder', 'Note'])
                 from cubes.fakeemail.__pkginfo__ import version as email_version
@@ -719,6 +721,24 @@
             self.assertEqual(tel, 1.0)
             self.assertIsInstance(tel, float)
 
+    def test_drop_required_inlined_relation(self):
+        with self.mh() as (cnx, mh):
+            bob = mh.cmd_create_entity('Personne', nom=u'bob')
+            note = mh.cmd_create_entity('Note', ecrit_par=bob)
+            mh.commit()
+            rdef = mh.fs_schema.rschema('ecrit_par').rdefs[('Note', 'Personne')]
+            with tempattr(rdef, 'cardinality', '1*'):
+                mh.sync_schema_props_perms('ecrit_par', syncperms=False)
+            mh.cmd_drop_relation_type('ecrit_par')
+            self.assertNotIn('%secrit_par' % SQL_PREFIX,
+                             self.table_schema(mh, '%sPersonne' % SQL_PREFIX))
+
+    def test_drop_inlined_rdef_delete_data(self):
+        with self.mh() as (cnx, mh):
+            note = mh.cmd_create_entity('Note', ecrit_par=cnx.user.eid)
+            mh.commit()
+            mh.drop_relation_definition('Note', 'ecrit_par', 'CWUser')
+            self.assertFalse(mh.sqlexec('SELECT * FROM cw_Note WHERE cw_ecrit_par IS NOT NULL'))
 
 class MigrationCommandsComputedTC(MigrationTC):
     """ Unit tests for computed relations and attributes
@@ -784,6 +804,20 @@
             self.assertEqual(self.schema['whatever'].subjects(), ('Company',))
             self.assertFalse(self.table_sql(mh, 'whatever_relation'))
 
+    def test_computed_relation_sync_schema_props_perms_security(self):
+        with self.mh() as (cnx, mh):
+            rdef = next(iter(self.schema['perm_changes'].rdefs.values()))
+            self.assertEqual(rdef.permissions,
+                             {'add': (), 'delete': (),
+                              'read': ('managers', 'users')})
+            mh.cmd_sync_schema_props_perms('perm_changes')
+            self.assertEqual(self.schema['perm_changes'].permissions,
+                             {'read': ('managers',)})
+            rdef = next(iter(self.schema['perm_changes'].rdefs.values()))
+            self.assertEqual(rdef.permissions,
+                             {'add': (), 'delete': (),
+                              'read': ('managers',)})
+
     def test_computed_relation_sync_schema_props_perms_on_rdef(self):
         self.assertIn('whatever', self.schema)
         with self.mh() as (cnx, mh):
--- a/server/test/unittest_postgres.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/test/unittest_postgres.py	Thu Dec 10 12:34:15 2015 +0100
@@ -19,8 +19,11 @@
 from datetime import datetime
 from threading import Thread
 
+from six.moves import range
+
 from logilab.common.testlib import SkipTest
 
+import logilab.database as lgdb
 from cubicweb import ValidationError
 from cubicweb.devtools import PostgresApptestConfiguration, startpgcluster, stoppgcluster
 from cubicweb.devtools.testlib import CubicWebTC
@@ -49,13 +52,21 @@
 class PostgresFTITC(CubicWebTC):
     configcls = PostgresTimeoutConfiguration
 
+    @classmethod
+    def setUpClass(cls):
+        cls.orig_connect_hooks = lgdb.SQL_CONNECT_HOOKS['postgres'][:]
+
+    @classmethod
+    def tearDownClass(cls):
+        lgdb.SQL_CONNECT_HOOKS['postgres'] = cls.orig_connect_hooks
+
     def test_eid_range(self):
         # concurrent allocation of eid ranges
         source = self.session.repo.sources_by_uri['system']
         range1 = []
         range2 = []
         def allocate_eid_ranges(session, target):
-            for x in xrange(1, 10):
+            for x in range(1, 10):
                 eid = source.create_eid(session, count=x)
                 target.extend(range(eid-x, eid))
 
--- a/server/test/unittest_querier.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/test/unittest_querier.py	Thu Dec 10 12:34:15 2015 +0100
@@ -21,6 +21,7 @@
 
 from datetime import date, datetime, timedelta, tzinfo
 
+from six import PY2, integer_types, binary_type, text_type
 from logilab.common.testlib import TestCase, unittest_main
 from rql import BadRQLQuery, RQLSyntaxError
 
@@ -129,8 +130,8 @@
 
     def assertRQLEqual(self, expected, got):
         from rql import parse
-        self.assertMultiLineEqual(unicode(parse(expected)),
-                                  unicode(parse(got)))
+        self.assertMultiLineEqual(text_type(parse(expected)),
+                                  text_type(parse(got)))
 
     def test_preprocess_security(self):
         s = self.user_groups_session('users')
@@ -178,46 +179,46 @@
                                 '        Comment, Division, Email, EmailPart, EmailThread, ExternalUri, File, Folder, '
                                 '        Frozable, Note, Old, Personne, RQLExpression, Societe, State, SubDivision, '
                                 '        SubWorkflowExitPoint, Tag, TrInfo, Transition, Workflow, WorkflowTransition)')
-            self.assertListEqual(sorted(solutions),
-                                  sorted([{'X': 'BaseTransition', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'Bookmark', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'Card', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'Comment', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'Division', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'CWCache', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'CWComputedRType', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'CWConstraint', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'CWConstraintType', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'CWEType', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'CWAttribute', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'CWGroup', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'CWRelation', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'CWPermission', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'CWProperty', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'CWRType', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'CWSource', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'CWUniqueTogetherConstraint', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'CWUser', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'Email', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'EmailPart', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'EmailThread', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'ExternalUri', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'File', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'Folder', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'Frozable', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'Note', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'Old', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'Personne', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'RQLExpression', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'Societe', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'State', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'SubDivision', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'SubWorkflowExitPoint', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'Tag', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'Transition', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'TrInfo', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'Workflow', 'ETN': 'String', 'ET': 'CWEType'},
-                                          {'X': 'WorkflowTransition', 'ETN': 'String', 'ET': 'CWEType'}]))
+            self.assertCountEqual(solutions,
+                                  [{'X': 'BaseTransition', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'Bookmark', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'Card', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'Comment', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'Division', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'CWCache', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'CWComputedRType', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'CWConstraint', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'CWConstraintType', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'CWEType', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'CWAttribute', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'CWGroup', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'CWRelation', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'CWPermission', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'CWProperty', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'CWRType', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'CWSource', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'CWUniqueTogetherConstraint', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'CWUser', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'Email', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'EmailPart', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'EmailThread', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'ExternalUri', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'File', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'Folder', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'Frozable', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'Note', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'Old', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'Personne', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'RQLExpression', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'Societe', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'State', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'SubDivision', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'SubWorkflowExitPoint', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'Tag', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'Transition', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'TrInfo', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'Workflow', 'ETN': 'String', 'ET': 'CWEType'},
+                                   {'X': 'WorkflowTransition', 'ETN': 'String', 'ET': 'CWEType'}])
             rql, solutions = partrqls[2]
             self.assertEqual(rql,
                              'Any ETN,X WHERE X is ET, ET name ETN, EXISTS(%(D)s use_email X), '
@@ -263,8 +264,9 @@
         self.assertEqual(rset.description[0][0], 'Datetime')
         rset = self.qexecute('Any %(x)s', {'x': 1})
         self.assertEqual(rset.description[0][0], 'Int')
-        rset = self.qexecute('Any %(x)s', {'x': 1L})
-        self.assertEqual(rset.description[0][0], 'Int')
+        if PY2:
+            rset = self.qexecute('Any %(x)s', {'x': long(1)})
+            self.assertEqual(rset.description[0][0], 'Int')
         rset = self.qexecute('Any %(x)s', {'x': True})
         self.assertEqual(rset.description[0][0], 'Boolean')
         rset = self.qexecute('Any %(x)s', {'x': 1.0})
@@ -307,10 +309,6 @@
     setUpClass = classmethod(setUpClass)
     tearDownClass = classmethod(tearDownClass)
 
-    def test_encoding_pb(self):
-        self.assertRaises(RQLSyntaxError, self.qexecute,
-                          'Any X WHERE X is CWRType, X name "öwned_by"')
-
     def test_unknown_eid(self):
         # should return an empty result set
         self.assertFalse(self.qexecute('Any X WHERE X eid 99999999'))
@@ -318,15 +316,15 @@
     def test_typed_eid(self):
         # should return an empty result set
         rset = self.qexecute('Any X WHERE X eid %(x)s', {'x': '1'})
-        self.assertIsInstance(rset[0][0], (int, long))
+        self.assertIsInstance(rset[0][0], integer_types)
 
     def test_bytes_storage(self):
         feid = self.qexecute('INSERT File X: X data_name "foo.pdf", '
                              'X data_format "text/plain", X data %(data)s',
-                            {'data': Binary("xxx")})[0][0]
+                            {'data': Binary(b"xxx")})[0][0]
         fdata = self.qexecute('Any D WHERE X data D, X eid %(x)s', {'x': feid})[0][0]
         self.assertIsInstance(fdata, Binary)
-        self.assertEqual(fdata.getvalue(), 'xxx')
+        self.assertEqual(fdata.getvalue(), b'xxx')
 
     # selection queries tests #################################################
 
@@ -886,18 +884,18 @@
     def test_select_constant(self):
         rset = self.qexecute('Any X, "toto" ORDERBY X WHERE X is CWGroup')
         self.assertEqual(rset.rows,
-                          map(list, zip((2,3,4,5), ('toto','toto','toto','toto',))))
-        self.assertIsInstance(rset[0][1], unicode)
+                         [list(x) for x in zip((2,3,4,5), ('toto','toto','toto','toto',))])
+        self.assertIsInstance(rset[0][1], text_type)
         self.assertEqual(rset.description,
-                          zip(('CWGroup', 'CWGroup', 'CWGroup', 'CWGroup'),
-                              ('String', 'String', 'String', 'String',)))
+                         list(zip(('CWGroup', 'CWGroup', 'CWGroup', 'CWGroup'),
+                                  ('String', 'String', 'String', 'String',))))
         rset = self.qexecute('Any X, %(value)s ORDERBY X WHERE X is CWGroup', {'value': 'toto'})
         self.assertEqual(rset.rows,
-                          map(list, zip((2,3,4,5), ('toto','toto','toto','toto',))))
-        self.assertIsInstance(rset[0][1], unicode)
+                         list(map(list, zip((2,3,4,5), ('toto','toto','toto','toto',)))))
+        self.assertIsInstance(rset[0][1], text_type)
         self.assertEqual(rset.description,
-                          zip(('CWGroup', 'CWGroup', 'CWGroup', 'CWGroup'),
-                              ('String', 'String', 'String', 'String',)))
+                         list(zip(('CWGroup', 'CWGroup', 'CWGroup', 'CWGroup'),
+                                  ('String', 'String', 'String', 'String',))))
         rset = self.qexecute('Any X,GN WHERE X is CWUser, G is CWGroup, X login "syt", '
                              'X in_group G, G name GN')
 
@@ -1015,7 +1013,7 @@
         self.assertEqual(len(rset.rows), 1)
         self.assertEqual(rset.description, [('Personne',)])
         rset = self.qexecute('Personne X WHERE X nom "bidule"')
-        self.assert_(rset.rows)
+        self.assertTrue(rset.rows)
         self.assertEqual(rset.description, [('Personne',)])
 
     def test_insert_1_multiple(self):
@@ -1029,20 +1027,20 @@
         rset = self.qexecute("INSERT Personne X, Personne Y: X nom 'bidule', Y nom 'tutu'")
         self.assertEqual(rset.description, [('Personne', 'Personne')])
         rset = self.qexecute('Personne X WHERE X nom "bidule" or X nom "tutu"')
-        self.assert_(rset.rows)
+        self.assertTrue(rset.rows)
         self.assertEqual(rset.description, [('Personne',), ('Personne',)])
 
     def test_insert_3(self):
         self.qexecute("INSERT Personne X: X nom Y WHERE U login 'admin', U login Y")
         rset = self.qexecute('Personne X WHERE X nom "admin"')
-        self.assert_(rset.rows)
+        self.assertTrue(rset.rows)
         self.assertEqual(rset.description, [('Personne',)])
 
     def test_insert_4(self):
         self.qexecute("INSERT Societe Y: Y nom 'toto'")
         self.qexecute("INSERT Personne X: X nom 'bidule', X travaille Y WHERE Y nom 'toto'")
         rset = self.qexecute('Any X, Y WHERE X nom "bidule", Y nom "toto", X travaille Y')
-        self.assert_(rset.rows)
+        self.assertTrue(rset.rows)
         self.assertEqual(rset.description, [('Personne', 'Societe',)])
 
     def test_insert_4bis(self):
@@ -1057,17 +1055,17 @@
     def test_insert_4ter(self):
         peid = self.qexecute("INSERT Personne X: X nom 'bidule'")[0][0]
         seid = self.qexecute("INSERT Societe Y: Y nom 'toto', X travaille Y WHERE X eid %(x)s",
-                             {'x': unicode(peid)})[0][0]
+                             {'x': text_type(peid)})[0][0]
         self.assertEqual(len(self.qexecute('Any X, Y WHERE X travaille Y')), 1)
         self.qexecute("INSERT Personne X: X nom 'chouette', X travaille Y WHERE Y eid %(x)s",
-                      {'x': unicode(seid)})
+                      {'x': text_type(seid)})
         self.assertEqual(len(self.qexecute('Any X, Y WHERE X travaille Y')), 2)
 
     def test_insert_5(self):
         self.qexecute("INSERT Personne X: X nom 'bidule'")
         self.qexecute("INSERT Societe Y: Y nom 'toto', X travaille Y WHERE X nom 'bidule'")
         rset = self.qexecute('Any X, Y WHERE X nom "bidule", Y nom "toto", X travaille Y')
-        self.assert_(rset.rows)
+        self.assertTrue(rset.rows)
         self.assertEqual(rset.description, [('Personne', 'Societe',)])
 
     def test_insert_5bis(self):
@@ -1075,20 +1073,20 @@
         self.qexecute("INSERT Societe Y: Y nom 'toto', X travaille Y WHERE X eid %(x)s",
                      {'x': peid})
         rset = self.qexecute('Any X, Y WHERE X nom "bidule", Y nom "toto", X travaille Y')
-        self.assert_(rset.rows)
+        self.assertTrue(rset.rows)
         self.assertEqual(rset.description, [('Personne', 'Societe',)])
 
     def test_insert_6(self):
         self.qexecute("INSERT Personne X, Societe Y: X nom 'bidule', Y nom 'toto', X travaille Y")
         rset = self.qexecute('Any X, Y WHERE X nom "bidule", Y nom "toto", X travaille Y')
-        self.assert_(rset.rows)
+        self.assertTrue(rset.rows)
         self.assertEqual(rset.description, [('Personne', 'Societe',)])
 
     def test_insert_7(self):
         self.qexecute("INSERT Personne X, Societe Y: X nom N, Y nom 'toto', "
                       "X travaille Y WHERE U login 'admin', U login N")
         rset = self.qexecute('Any X, Y WHERE X nom "admin", Y nom "toto", X travaille Y')
-        self.assert_(rset.rows)
+        self.assertTrue(rset.rows)
         self.assertEqual(rset.description, [('Personne', 'Societe',)])
 
     def test_insert_7_2(self):
@@ -1103,7 +1101,7 @@
         self.qexecute("INSERT Societe Y, Personne X: Y nom N, X nom 'toto', X travaille Y "
                       "WHERE U login 'admin', U login N")
         rset = self.qexecute('Any X, Y WHERE X nom "toto", Y nom "admin", X travaille Y')
-        self.assert_(rset.rows)
+        self.assertTrue(rset.rows)
         self.assertEqual(rset.description, [('Personne', 'Societe',)])
 
     def test_insert_9(self):
@@ -1267,7 +1265,7 @@
         rset = self.qexecute("INSERT Personne X, Societe Y: X nom 'bidule', Y nom 'toto'")
         eid1, eid2 = rset[0][0], rset[0][1]
         self.qexecute("SET X travaille Y WHERE X eid %(x)s, Y eid %(y)s",
-                      {'x': unicode(eid1), 'y': unicode(eid2)})
+                      {'x': text_type(eid1), 'y': text_type(eid2)})
         rset = self.qexecute('Any X, Y WHERE X travaille Y')
         self.assertEqual(len(rset.rows), 1)
 
@@ -1317,7 +1315,7 @@
         eid1, eid2 = rset[0][0], rset[0][1]
         rset = self.qexecute("SET X travaille Y WHERE X eid %(x)s, Y eid %(y)s, "
                             "NOT EXISTS(Z ecrit_par X)",
-                            {'x': unicode(eid1), 'y': unicode(eid2)})
+                            {'x': text_type(eid1), 'y': text_type(eid2)})
         self.assertEqual(tuplify(rset.rows), [(eid1, eid2)])
 
     def test_update_query_error(self):
@@ -1364,7 +1362,7 @@
             cursor = cnx.cnxset.cu
             cursor.execute("SELECT %supassword from %sCWUser WHERE %slogin='bob'"
                            % (SQL_PREFIX, SQL_PREFIX, SQL_PREFIX))
-            passwd = str(cursor.fetchone()[0])
+            passwd = binary_type(cursor.fetchone()[0])
             self.assertEqual(passwd, crypt_password('toto', passwd))
         rset = self.qexecute("Any X WHERE X is CWUser, X login 'bob', X upassword %(pwd)s",
                             {'pwd': Binary(passwd)})
@@ -1377,11 +1375,11 @@
                                {'pwd': 'toto'})
             self.assertEqual(rset.description[0][0], 'CWUser')
             rset = cnx.execute("SET X upassword %(pwd)s WHERE X is CWUser, X login 'bob'",
-                               {'pwd': 'tutu'})
+                               {'pwd': b'tutu'})
             cursor = cnx.cnxset.cu
             cursor.execute("SELECT %supassword from %sCWUser WHERE %slogin='bob'"
                            % (SQL_PREFIX, SQL_PREFIX, SQL_PREFIX))
-            passwd = str(cursor.fetchone()[0])
+            passwd = binary_type(cursor.fetchone()[0])
             self.assertEqual(passwd, crypt_password('tutu', passwd))
             rset = cnx.execute("Any X WHERE X is CWUser, X login 'bob', X upassword %(pwd)s",
                                {'pwd': Binary(passwd)})
--- a/server/test/unittest_repository.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/test/unittest_repository.py	Thu Dec 10 12:34:15 2015 +0100
@@ -22,6 +22,8 @@
 import time
 import logging
 
+from six.moves import range
+
 from yams.constraints import UniqueConstraint
 from yams import register_base_type, unregister_base_type
 
@@ -77,7 +79,7 @@
 
     def test_connect(self):
         cnxid = self.repo.connect(self.admlogin, password=self.admpassword)
-        self.assert_(cnxid)
+        self.assertTrue(cnxid)
         self.repo.close(cnxid)
         self.assertRaises(AuthenticationError,
                           self.repo.connect, self.admlogin, password='nimportnawak')
@@ -100,7 +102,7 @@
             cnx.commit()
         repo = self.repo
         cnxid = repo.connect(u"barnabé", password=u"héhéhé".encode('UTF8'))
-        self.assert_(cnxid)
+        self.assertTrue(cnxid)
         repo.close(cnxid)
 
     def test_rollback_on_execute_validation_error(self):
@@ -145,7 +147,7 @@
     def test_close(self):
         repo = self.repo
         cnxid = repo.connect(self.admlogin, password=self.admpassword)
-        self.assert_(cnxid)
+        self.assertTrue(cnxid)
         repo.close(cnxid)
 
     def test_check_session(self):
@@ -192,7 +194,7 @@
         constraints = schema.rschema('relation_type').rdef('CWAttribute', 'CWRType').constraints
         self.assertEqual(len(constraints), 1)
         cstr = constraints[0]
-        self.assert_(isinstance(cstr, RQLConstraint))
+        self.assertIsInstance(cstr, RQLConstraint)
         self.assertEqual(cstr.expression, 'O final TRUE')
 
         ownedby = schema.rschema('owned_by')
@@ -589,11 +591,11 @@
         with self.admin_access.repo_cnx() as cnx:
             personnes = []
             t0 = time.time()
-            for i in xrange(2000):
+            for i in range(2000):
                 p = cnx.create_entity('Personne', nom=u'Doe%03d'%i, prenom=u'John', sexe=u'M')
                 personnes.append(p)
             abraham = cnx.create_entity('Personne', nom=u'Abraham', prenom=u'John', sexe=u'M')
-            for j in xrange(0, 2000, 100):
+            for j in range(0, 2000, 100):
                 abraham.cw_set(personne_composite=personnes[j:j+100])
             t1 = time.time()
             self.info('creation: %.2gs', (t1 - t0))
@@ -610,7 +612,7 @@
     def test_add_relation_non_inlined(self):
         with self.admin_access.repo_cnx() as cnx:
             personnes = []
-            for i in xrange(2000):
+            for i in range(2000):
                 p = cnx.create_entity('Personne', nom=u'Doe%03d'%i, prenom=u'John', sexe=u'M')
                 personnes.append(p)
             cnx.commit()
@@ -619,7 +621,7 @@
                                         personne_composite=personnes[:100])
             t1 = time.time()
             self.info('creation: %.2gs', (t1 - t0))
-            for j in xrange(100, 2000, 100):
+            for j in range(100, 2000, 100):
                 abraham.cw_set(personne_composite=personnes[j:j+100])
             t2 = time.time()
             self.info('more relations: %.2gs', (t2-t1))
@@ -630,7 +632,7 @@
     def test_add_relation_inlined(self):
         with self.admin_access.repo_cnx() as cnx:
             personnes = []
-            for i in xrange(2000):
+            for i in range(2000):
                 p = cnx.create_entity('Personne', nom=u'Doe%03d'%i, prenom=u'John', sexe=u'M')
                 personnes.append(p)
             cnx.commit()
@@ -639,7 +641,7 @@
                                         personne_inlined=personnes[:100])
             t1 = time.time()
             self.info('creation: %.2gs', (t1 - t0))
-            for j in xrange(100, 2000, 100):
+            for j in range(100, 2000, 100):
                 abraham.cw_set(personne_inlined=personnes[j:j+100])
             t2 = time.time()
             self.info('more relations: %.2gs', (t2-t1))
@@ -652,7 +654,7 @@
         """ to be compared with test_session_add_relations"""
         with self.admin_access.repo_cnx() as cnx:
             personnes = []
-            for i in xrange(2000):
+            for i in range(2000):
                 p = cnx.create_entity('Personne', nom=u'Doe%03d'%i, prenom=u'John', sexe=u'M')
                 personnes.append(p)
             abraham = cnx.create_entity('Personne', nom=u'Abraham', prenom=u'John', sexe=u'M')
@@ -669,7 +671,7 @@
         """ to be compared with test_session_add_relation"""
         with self.admin_access.repo_cnx() as cnx:
             personnes = []
-            for i in xrange(2000):
+            for i in range(2000):
                 p = cnx.create_entity('Personne', nom=u'Doe%03d'%i, prenom=u'John', sexe=u'M')
                 personnes.append(p)
             abraham = cnx.create_entity('Personne', nom=u'Abraham', prenom=u'John', sexe=u'M')
@@ -686,7 +688,7 @@
         """ to be compared with test_session_add_relations"""
         with self.admin_access.repo_cnx() as cnx:
             personnes = []
-            for i in xrange(2000):
+            for i in range(2000):
                 p = cnx.create_entity('Personne', nom=u'Doe%03d'%i, prenom=u'John', sexe=u'M')
                 personnes.append(p)
             abraham = cnx.create_entity('Personne', nom=u'Abraham', prenom=u'John', sexe=u'M')
@@ -703,7 +705,7 @@
         """ to be compared with test_session_add_relation"""
         with self.admin_access.repo_cnx() as cnx:
             personnes = []
-            for i in xrange(2000):
+            for i in range(2000):
                 p = cnx.create_entity('Personne', nom=u'Doe%03d'%i, prenom=u'John', sexe=u'M')
                 personnes.append(p)
             abraham = cnx.create_entity('Personne', nom=u'Abraham', prenom=u'John', sexe=u'M')
--- a/server/test/unittest_rql2sql.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/test/unittest_rql2sql.py	Thu Dec 10 12:34:15 2015 +0100
@@ -16,6 +16,7 @@
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """unit tests for module cubicweb.server.sources.rql2sql"""
+from __future__ import print_function
 
 import sys
 import os
@@ -1246,13 +1247,13 @@
         except Exception as ex:
             if 'r' in locals():
                 try:
-                    print (r%args).strip()
+                    print((r%args).strip())
                 except KeyError:
-                    print 'strange, missing substitution'
-                    print r, nargs
-                print '!='
-                print sql.strip()
-            print 'RQL:', rql
+                    print('strange, missing substitution')
+                    print(r, nargs)
+                print('!=')
+                print(sql.strip())
+            print('RQL:', rql)
             raise
 
     def _parse(self, rqls):
@@ -1269,11 +1270,11 @@
             r, args, cbs = self.o.generate(rqlst, args)
             self.assertEqual((r.strip(), args), sql)
         except Exception as ex:
-            print rql
+            print(rql)
             if 'r' in locals():
-                print r.strip()
-                print '!='
-                print sql[0].strip()
+                print(r.strip())
+                print('!=')
+                print(sql[0].strip())
             raise
         return
 
--- a/server/test/unittest_rqlannotation.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/test/unittest_rqlannotation.py	Thu Dec 10 12:34:15 2015 +0100
@@ -64,7 +64,7 @@
             rqlst = self._prepare(cnx, 'Any A,B,C WHERE A eid 12,A comment B, '
                                   'A ?wf_info_for C')
             self.assertEqual(rqlst.defined_vars['A']._q_invariant, False)
-            self.assert_(rqlst.defined_vars['B'].stinfo['attrvar'])
+            self.assertTrue(rqlst.defined_vars['B'].stinfo['attrvar'])
             self.assertEqual(rqlst.defined_vars['C']._q_invariant, False)
             self.assertEqual(rqlst.solutions, [{'A': 'TrInfo', 'B': 'String', 'C': 'Affaire'},
                                           {'A': 'TrInfo', 'B': 'String', 'C': 'CWUser'},
@@ -87,7 +87,7 @@
                                   'Y nom NX, X eid XE, not Y eid XE')
             self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
             self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
-            self.assert_(rqlst.defined_vars['XE'].stinfo['attrvar'])
+            self.assertTrue(rqlst.defined_vars['XE'].stinfo['attrvar'])
 
     def test_0_8(self):
         with self.session.new_cnx() as cnx:
--- a/server/test/unittest_schemaserial.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/test/unittest_schemaserial.py	Thu Dec 10 12:34:15 2015 +0100
@@ -292,7 +292,7 @@
                       {'cardinality': u'?1',
                        'defaultval': None,
                        'description': u'',
-                       'extra_props': '{"jungle_speed": 42}',
+                       'extra_props': b'{"jungle_speed": 42}',
                        'formula': None,
                        'indexed': False,
                        'oe': None,
--- a/server/test/unittest_security.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/test/unittest_security.py	Thu Dec 10 12:34:15 2015 +0100
@@ -17,6 +17,8 @@
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """functional tests for server'security"""
 
+from six.moves import range
+
 from logilab.common.testlib import unittest_main
 
 from cubicweb.devtools.testlib import CubicWebTC
@@ -33,7 +35,7 @@
         with self.admin_access.client_cnx() as cnx:
             self.create_user(cnx, u'iaminusersgrouponly')
             hash = _CRYPTO_CTX.encrypt('oldpassword', scheme='des_crypt')
-            self.create_user(cnx, u'oldpassword', password=Binary(hash))
+            self.create_user(cnx, u'oldpassword', password=Binary(hash.encode('ascii')))
 
 class LowLevelSecurityFunctionTC(BaseSecurityTC):
 
@@ -79,17 +81,20 @@
         it will be updated on next login
         """
         with self.repo.internal_cnx() as cnx:
-            oldhash = str(cnx.system_sql("SELECT cw_upassword FROM cw_CWUser "
-                                         "WHERE cw_login = 'oldpassword'").fetchone()[0])
+            oldhash = cnx.system_sql("SELECT cw_upassword FROM cw_CWUser "
+                                         "WHERE cw_login = 'oldpassword'").fetchone()[0]
+            oldhash = self.repo.system_source.binary_to_str(oldhash)
             self.repo.close(self.repo.connect('oldpassword', password='oldpassword'))
-            newhash = str(cnx.system_sql("SELECT cw_upassword FROM cw_CWUser "
-                                         "WHERE cw_login = 'oldpassword'").fetchone()[0])
+            newhash = cnx.system_sql("SELECT cw_upassword FROM cw_CWUser "
+                                     "WHERE cw_login = 'oldpassword'").fetchone()[0]
+            newhash = self.repo.system_source.binary_to_str(newhash)
             self.assertNotEqual(oldhash, newhash)
-            self.assertTrue(newhash.startswith('$6$'))
+            self.assertTrue(newhash.startswith(b'$6$'))
             self.repo.close(self.repo.connect('oldpassword', password='oldpassword'))
-            self.assertEqual(newhash,
-                             str(cnx.system_sql("SELECT cw_upassword FROM cw_CWUser WHERE "
-                                                "cw_login = 'oldpassword'").fetchone()[0]))
+            newnewhash = cnx.system_sql("SELECT cw_upassword FROM cw_CWUser WHERE "
+                                        "cw_login = 'oldpassword'").fetchone()[0]
+            newnewhash = self.repo.system_source.binary_to_str(newnewhash)
+            self.assertEqual(newhash, newnewhash)
 
 
 class SecurityRewritingTC(BaseSecurityTC):
@@ -293,7 +298,7 @@
             ueid = self.create_user(cnx, u'user').eid
         with self.new_access(u'user').repo_cnx() as cnx:
             cnx.execute('SET X upassword %(passwd)s WHERE X eid %(x)s',
-                       {'x': ueid, 'passwd': 'newpwd'})
+                       {'x': ueid, 'passwd': b'newpwd'})
             cnx.commit()
         self.repo.close(self.repo.connect('user', password='newpwd'))
 
@@ -302,7 +307,7 @@
             ueid = self.create_user(cnx, u'otheruser').eid
         with self.new_access(u'iaminusersgrouponly').repo_cnx() as cnx:
             cnx.execute('SET X upassword %(passwd)s WHERE X eid %(x)s',
-                       {'x': ueid, 'passwd': 'newpwd'})
+                       {'x': ueid, 'passwd': b'newpwd'})
             self.assertRaises(Unauthorized, cnx.commit)
 
     # read security test
@@ -559,7 +564,7 @@
             rset = cnx.execute('CWUser X')
             self.assertEqual([[anon.eid]], rset.rows)
             # anonymous user can read groups (necessary to check allowed transitions for instance)
-            self.assert_(cnx.execute('CWGroup X'))
+            self.assertTrue(cnx.execute('CWGroup X'))
             # should only be able to read the anonymous user, not another one
             self.assertRaises(Unauthorized,
                               cnx.execute, 'CWUser X WHERE X eid %(x)s', {'x': admineid})
@@ -666,7 +671,7 @@
                 rset = cnx.execute('Any X, U WHERE X is EmailAddress, U use_email X')
                 msg = ['Preexisting email readable by anon found!']
                 tmpl = '  - "%s" used by user "%s"'
-                for i in xrange(len(rset)):
+                for i in range(len(rset)):
                     email, user = rset.get_entity(i, 0), rset.get_entity(i, 1)
                     msg.append(tmpl % (email.dc_title(), user.dc_title()))
                 raise RuntimeError('\n'.join(msg))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/test/unittest_serverctl.py	Thu Dec 10 12:34:15 2015 +0100
@@ -0,0 +1,26 @@
+import os.path as osp
+import shutil
+
+from cubicweb.devtools import testlib, ApptestConfiguration
+from cubicweb.server.serverctl import _local_dump, DBDumpCommand
+from cubicweb.server.serverconfig import ServerConfiguration
+
+class ServerCTLTC(testlib.CubicWebTC):
+    def setUp(self):
+        super(ServerCTLTC, self).setUp()
+        self.orig_config_for = ServerConfiguration.config_for
+        config_for = lambda appid: ApptestConfiguration(appid, apphome=self.datadir)
+        ServerConfiguration.config_for = staticmethod(config_for)
+
+    def tearDown(self):
+        ServerConfiguration.config_for = self.orig_config_for
+        super(ServerCTLTC, self).tearDown()
+
+    def test_dump(self):
+        DBDumpCommand(None).run([self.appid])
+        shutil.rmtree(osp.join(self.config.apphome, 'backup'))
+
+
+if __name__ == '__main__':
+    from unittest import main
+    main()
--- a/server/test/unittest_storage.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/test/unittest_storage.py	Thu Dec 10 12:34:15 2015 +0100
@@ -17,12 +17,15 @@
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """unit tests for module cubicweb.server.sources.storages"""
 
+from six import PY2
+
 from logilab.common.testlib import unittest_main, tag, Tags
 from cubicweb.devtools.testlib import CubicWebTC
 
 from glob import glob
 import os
 import os.path as osp
+import sys
 import shutil
 import tempfile
 
@@ -57,24 +60,26 @@
     def setup_database(self):
         self.tempdir = tempfile.mkdtemp()
         bfs_storage = storages.BytesFileSystemStorage(self.tempdir)
+        self.bfs_storage = bfs_storage
         storages.set_attribute_storage(self.repo, 'File', 'data', bfs_storage)
         storages.set_attribute_storage(self.repo, 'BFSSTestable', 'opt_attr', bfs_storage)
 
     def tearDown(self):
         super(StorageTC, self).tearDown()
         storages.unset_attribute_storage(self.repo, 'File', 'data')
+        del self.bfs_storage
         shutil.rmtree(self.tempdir)
 
 
-    def create_file(self, cnx, content='the-data'):
+    def create_file(self, cnx, content=b'the-data'):
         return cnx.create_entity('File', data=Binary(content),
                                  data_format=u'text/plain',
                                  data_name=u'foo.pdf')
 
     def fspath(self, cnx, entity):
         fspath = cnx.execute('Any fspath(D) WHERE F eid %(f)s, F data D',
-                             {'f': entity.eid})[0][0]
-        return fspath.getvalue()
+                             {'f': entity.eid})[0][0].getvalue()
+        return fspath if PY2 else fspath.decode('utf-8')
 
     def test_bfss_wrong_fspath_usage(self):
         with self.admin_access.repo_cnx() as cnx:
@@ -109,7 +114,7 @@
 
             # add f1 back to the entity cache with req as _cw
             f1 = req.entity_from_eid(f1.eid)
-            f1.cw_set(data=Binary('the new data'))
+            f1.cw_set(data=Binary(b'the new data'))
             cnx.rollback()
             self.assertEqual(open(expected_filepath).read(), 'the-data')
             f1.cw_delete()
@@ -132,7 +137,7 @@
         with self.admin_access.repo_cnx() as cnx:
             cnx.transaction_data['fs_importing'] = True
             filepath = osp.abspath(__file__)
-            f1 = cnx.create_entity('File', data=Binary(filepath),
+            f1 = cnx.create_entity('File', data=Binary(filepath.encode(sys.getfilesystemencoding())),
                                    data_format=u'text/plain', data_name=u'foo')
             self.assertEqual(self.fspath(cnx, f1), filepath)
 
@@ -185,8 +190,8 @@
             self.assertEqual(len(rset), 2)
             self.assertEqual(rset[0][0], f1.eid)
             self.assertEqual(rset[1][0], f1.eid)
-            self.assertEqual(rset[0][1].getvalue(), 'the-data')
-            self.assertEqual(rset[1][1].getvalue(), 'the-data')
+            self.assertEqual(rset[0][1].getvalue(), b'the-data')
+            self.assertEqual(rset[1][1].getvalue(), b'the-data')
             rset = cnx.execute('Any X,LENGTH(D) WHERE X eid %(x)s, X data D',
                                 {'x': f1.eid})
             self.assertEqual(len(rset), 1)
@@ -212,31 +217,31 @@
         with self.admin_access.repo_cnx() as cnx:
             cnx.transaction_data['fs_importing'] = True
             filepath = osp.abspath(__file__)
-            f1 = cnx.create_entity('File', data=Binary(filepath),
+            f1 = cnx.create_entity('File', data=Binary(filepath.encode(sys.getfilesystemencoding())),
                                    data_format=u'text/plain', data_name=u'foo')
             cw_value = f1.data.getvalue()
-            fs_value = file(filepath).read()
+            fs_value = open(filepath, 'rb').read()
             if cw_value != fs_value:
                 self.fail('cw value %r is different from file content' % cw_value)
 
     @tag('update')
     def test_bfss_update_with_existing_data(self):
         with self.admin_access.repo_cnx() as cnx:
-            f1 = cnx.create_entity('File', data=Binary('some data'),
+            f1 = cnx.create_entity('File', data=Binary(b'some data'),
                                    data_format=u'text/plain', data_name=u'foo')
             # NOTE: do not use cw_set() which would automatically
             #       update f1's local dict. We want the pure rql version to work
             cnx.execute('SET F data %(d)s WHERE F eid %(f)s',
-                         {'d': Binary('some other data'), 'f': f1.eid})
-            self.assertEqual(f1.data.getvalue(), 'some other data')
+                         {'d': Binary(b'some other data'), 'f': f1.eid})
+            self.assertEqual(f1.data.getvalue(), b'some other data')
             cnx.commit()
             f2 = cnx.execute('Any F WHERE F eid %(f)s, F is File', {'f': f1.eid}).get_entity(0, 0)
-            self.assertEqual(f2.data.getvalue(), 'some other data')
+            self.assertEqual(f2.data.getvalue(), b'some other data')
 
     @tag('update', 'extension', 'commit')
     def test_bfss_update_with_different_extension_commited(self):
         with self.admin_access.repo_cnx() as cnx:
-            f1 = cnx.create_entity('File', data=Binary('some data'),
+            f1 = cnx.create_entity('File', data=Binary(b'some data'),
                                    data_format=u'text/plain', data_name=u'foo.txt')
             # NOTE: do not use cw_set() which would automatically
             #       update f1's local dict. We want the pure rql version to work
@@ -246,7 +251,7 @@
             self.assertEqual(osp.splitext(old_path)[1], '.txt')
             cnx.execute('SET F data %(d)s, F data_name %(dn)s, '
                          'F data_format %(df)s WHERE F eid %(f)s',
-                         {'d': Binary('some other data'), 'f': f1.eid,
+                         {'d': Binary(b'some other data'), 'f': f1.eid,
                           'dn': u'bar.jpg', 'df': u'image/jpeg'})
             cnx.commit()
             # the new file exists with correct extension
@@ -260,7 +265,7 @@
     @tag('update', 'extension', 'rollback')
     def test_bfss_update_with_different_extension_rolled_back(self):
         with self.admin_access.repo_cnx() as cnx:
-            f1 = cnx.create_entity('File', data=Binary('some data'),
+            f1 = cnx.create_entity('File', data=Binary(b'some data'),
                                    data_format=u'text/plain', data_name=u'foo.txt')
             # NOTE: do not use cw_set() which would automatically
             #       update f1's local dict. We want the pure rql version to work
@@ -271,7 +276,7 @@
             self.assertEqual(osp.splitext(old_path)[1], '.txt')
             cnx.execute('SET F data %(d)s, F data_name %(dn)s, '
                          'F data_format %(df)s WHERE F eid %(f)s',
-                         {'d': Binary('some other data'),
+                         {'d': Binary(b'some other data'),
                           'f': f1.eid,
                           'dn': u'bar.jpg',
                           'df': u'image/jpeg'})
@@ -290,7 +295,7 @@
     @tag('update', 'NULL')
     def test_bfss_update_to_None(self):
         with self.admin_access.repo_cnx() as cnx:
-            f = cnx.create_entity('Affaire', opt_attr=Binary('toto'))
+            f = cnx.create_entity('Affaire', opt_attr=Binary(b'toto'))
             cnx.commit()
             f.cw_set(opt_attr=None)
             cnx.commit()
@@ -298,17 +303,17 @@
     @tag('fs_importing', 'update')
     def test_bfss_update_with_fs_importing(self):
         with self.admin_access.repo_cnx() as cnx:
-            f1 = cnx.create_entity('File', data=Binary('some data'),
+            f1 = cnx.create_entity('File', data=Binary(b'some data'),
                                    data_format=u'text/plain',
                                    data_name=u'foo')
             old_fspath = self.fspath(cnx, f1)
             cnx.transaction_data['fs_importing'] = True
             new_fspath = osp.join(self.tempdir, 'newfile.txt')
-            file(new_fspath, 'w').write('the new data')
+            open(new_fspath, 'w').write('the new data')
             cnx.execute('SET F data %(d)s WHERE F eid %(f)s',
-                         {'d': Binary(new_fspath), 'f': f1.eid})
+                         {'d': Binary(new_fspath.encode(sys.getfilesystemencoding())), 'f': f1.eid})
             cnx.commit()
-            self.assertEqual(f1.data.getvalue(), 'the new data')
+            self.assertEqual(f1.data.getvalue(), b'the new data')
             self.assertEqual(self.fspath(cnx, f1), new_fspath)
             self.assertFalse(osp.isfile(old_fspath))
 
--- a/server/test/unittest_undo.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/test/unittest_undo.py	Thu Dec 10 12:34:15 2015 +0100
@@ -17,6 +17,8 @@
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 
+from six import text_type
+
 from cubicweb import ValidationError
 from cubicweb.devtools.testlib import CubicWebTC
 import cubicweb.server.session
@@ -255,7 +257,7 @@
                 "%s doesn't exist anymore." % g.eid])
             with self.assertRaises(ValidationError) as cm:
                 cnx.commit()
-            cm.exception.translate(unicode)
+            cm.exception.translate(text_type)
             self.assertEqual(cm.exception.entity, self.totoeid)
             self.assertEqual(cm.exception.errors,
                               {'in_group-subject': u'at least one relation in_group is '
@@ -461,7 +463,7 @@
     # problem occurs in string manipulation for python < 2.6
     def test___unicode__method(self):
         u = _UndoException(u"voilà")
-        self.assertIsInstance(unicode(u), unicode)
+        self.assertIsInstance(text_type(u), text_type)
 
 
 if __name__ == '__main__':
--- a/server/test/unittest_utils.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/test/unittest_utils.py	Thu Dec 10 12:34:15 2015 +0100
@@ -26,13 +26,13 @@
     def test_crypt(self):
         for hash in (
             utils.crypt_password('xxx'), # default sha512
-            'ab$5UsKFxRKKN.d8iBIFBnQ80', # custom md5
-            'ab4Vlm81ZUHlg', # DES
+            b'ab$5UsKFxRKKN.d8iBIFBnQ80', # custom md5
+            b'ab4Vlm81ZUHlg', # DES
             ):
             self.assertEqual(utils.crypt_password('xxx', hash), hash)
             self.assertEqual(utils.crypt_password(u'xxx', hash), hash)
-            self.assertEqual(utils.crypt_password(u'xxx', unicode(hash)), hash)
-            self.assertEqual(utils.crypt_password('yyy', hash), '')
+            self.assertEqual(utils.crypt_password(u'xxx', hash.decode('ascii')), hash.decode('ascii'))
+            self.assertEqual(utils.crypt_password('yyy', hash), b'')
 
         # accept any password for empty hashes (is it a good idea?)
         self.assertEqual(utils.crypt_password('xxx', ''), '')
--- a/server/utils.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/server/utils.py	Thu Dec 10 12:34:15 2015 +0100
@@ -16,6 +16,7 @@
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """Some utilities for the CubicWeb server."""
+from __future__ import print_function
 
 __docformat__ = "restructuredtext en"
 
@@ -24,6 +25,9 @@
 from threading import Timer, Thread
 from getpass import getpass
 
+from six import PY2, text_type
+from six.moves import input
+
 from passlib.utils import handlers as uh, to_hash_str
 from passlib.context import CryptContext
 
@@ -60,7 +64,7 @@
     """return the encrypted password using the given salt or a generated one
     """
     if salt is None:
-        return _CRYPTO_CTX.encrypt(passwd)
+        return _CRYPTO_CTX.encrypt(passwd).encode('ascii')
     # empty hash, accept any password for backwards compat
     if salt == '':
         return salt
@@ -70,7 +74,7 @@
     except ValueError: # e.g. couldn't identify hash
         pass
     # wrong password
-    return ''
+    return b''
 
 
 def eschema_eid(cnx, eschema):
@@ -81,7 +85,7 @@
     if eschema.eid is None:
         eschema.eid = cnx.execute(
             'Any X WHERE X is CWEType, X name %(name)s',
-            {'name': unicode(eschema)})[0][0]
+            {'name': text_type(eschema)})[0][0]
     return eschema.eid
 
 
@@ -92,17 +96,18 @@
                        passwdmsg='password'):
     if not user:
         if msg:
-            print msg
+            print(msg)
         while not user:
-            user = raw_input('login: ')
-        user = unicode(user, sys.stdin.encoding)
+            user = input('login: ')
+        if PY2:
+            user = unicode(user, sys.stdin.encoding)
     passwd = getpass('%s: ' % passwdmsg)
     if confirm:
         while True:
             passwd2 = getpass('confirm password: ')
             if passwd == passwd2:
                 break
-            print 'password doesn\'t match'
+            print('password doesn\'t match')
             passwd = getpass('password: ')
     # XXX decode password using stdin encoding then encode it using appl'encoding
     return user, passwd
@@ -236,4 +241,3 @@
 from logging import getLogger
 from cubicweb import set_log_methods
 set_log_methods(TasksManager, getLogger('cubicweb.repository'))
-
--- a/setup.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/setup.py	Thu Dec 10 12:34:15 2015 +0100
@@ -42,7 +42,7 @@
 from __pkginfo__ import modname, version, license, description, web, \
      author, author_email
 
-long_description = file('README').read()
+long_description = open('README').read()
 
 # import optional features
 import __pkginfo__
@@ -51,7 +51,7 @@
     for entry in ("__depends__",): # "__recommends__"):
         requires.update(getattr(__pkginfo__, entry, {}))
     install_requires = [("%s %s" % (d, v and v or "")).strip()
-                       for d, v in requires.iteritems()]
+                       for d, v in requires.items()]
 else:
     install_requires = []
 
--- a/skeleton/DISTNAME.spec.tmpl	Wed Dec 09 18:42:13 2015 +0100
+++ b/skeleton/DISTNAME.spec.tmpl	Thu Dec 10 12:34:15 2015 +0100
@@ -21,6 +21,7 @@
 
 BuildRequires:  %%{python} %%{python}-setuptools
 Requires:       cubicweb >= %(version)s
+Requires:       %{python}-six >= 1.4.0
 
 %%description
 %(longdesc)s
--- a/skeleton/debian/control.tmpl	Wed Dec 09 18:42:13 2015 +0100
+++ b/skeleton/debian/control.tmpl	Thu Dec 10 12:34:15 2015 +0100
@@ -12,6 +12,7 @@
 Architecture: all
 Depends:
  cubicweb-common (>= %(version)s),
+ python-six (>= 1.4.0),
  ${python:Depends},
  ${misc:Depends},
 Description: %(shortdesc)s
--- a/skeleton/debian/rules	Wed Dec 09 18:42:13 2015 +0100
+++ b/skeleton/debian/rules	Thu Dec 10 12:34:15 2015 +0100
@@ -5,10 +5,5 @@
 %:
 	dh $@ --with python2
 
-override_dh_auto_install:
-	dh_auto_install
-	# remove generated .egg-info file
-	rm -rf debian/*/usr/lib/python*
-
 override_dh_python2:
 	dh_python2 -i /usr/share/cubicweb
--- a/skeleton/setup.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/skeleton/setup.py	Thu Dec 10 12:34:15 2015 +0100
@@ -4,7 +4,7 @@
 # copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
-# This file is part of CubicWeb tag cube.
+# This file is part of CubicWeb.
 #
 # CubicWeb 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
@@ -44,7 +44,7 @@
     author, author_email, classifiers
 
 if exists('README'):
-    long_description = file('README').read()
+    long_description = open('README').read()
 else:
     long_description = ''
 
@@ -55,7 +55,7 @@
     for entry in ("__depends__",):  # "__recommends__"):
         requires.update(getattr(__pkginfo__, entry, {}))
     install_requires = [("%s %s" % (d, v and v or "")).strip()
-                        for d, v in requires.iteritems()]
+                        for d, v in requires.items()]
 else:
     install_requires = []
 
--- a/sobjects/__init__.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/sobjects/__init__.py	Thu Dec 10 12:34:15 2015 +0100
@@ -20,11 +20,11 @@
 import os.path as osp
 
 def registration_callback(vreg):
-    vreg.register_all(globals().itervalues(), __name__)
+    vreg.register_all(globals().values(), __name__)
     global URL_MAPPING
     URL_MAPPING = {}
     if vreg.config.apphome:
         url_mapping_file = osp.join(vreg.config.apphome, 'urlmapping.py')
         if osp.exists(url_mapping_file):
-            URL_MAPPING = eval(file(url_mapping_file).read())
+            URL_MAPPING = eval(open(url_mapping_file).read())
             vreg.info('using url mapping %s from %s', URL_MAPPING, url_mapping_file)
--- a/sobjects/cwxmlparser.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/sobjects/cwxmlparser.py	Thu Dec 10 12:34:15 2015 +0100
@@ -32,9 +32,11 @@
 """
 
 from datetime import datetime, time
-import urlparse
 import urllib
 
+from six import text_type
+from six.moves.urllib.parse import urlparse, urlunparse, parse_qs, urlencode
+
 from logilab.common.date import todate, totime
 from logilab.common.textutils import splitstrip, text_to_dict
 from logilab.common.decorators import classproperty
@@ -50,7 +52,7 @@
 # XXX see cubicweb.cwvreg.YAMS_TO_PY
 # XXX see cubicweb.web.views.xmlrss.SERIALIZERS
 DEFAULT_CONVERTERS = BASE_CONVERTERS.copy()
-DEFAULT_CONVERTERS['String'] = unicode
+DEFAULT_CONVERTERS['String'] = text_type
 DEFAULT_CONVERTERS['Password'] = lambda x: x.encode('utf8')
 def convert_date(ustr):
     return todate(datetime.strptime(ustr, '%Y-%m-%d'))
@@ -124,7 +126,7 @@
 
     def list_actions(self):
         reg = self._cw.vreg['components']
-        return sorted(clss[0].action for rid, clss in reg.iteritems()
+        return sorted(clss[0].action for rid, clss in reg.items()
                       if rid.startswith('cw.entityxml.action.'))
 
     # mapping handling #########################################################
@@ -204,7 +206,7 @@
         * `rels` is for relations and structured as
            {role: {relation: [(related item, related rels)...]}
         """
-        entity = self.extid2entity(str(item['cwuri']), item['cwtype'],
+        entity = self.extid2entity(item['cwuri'].encode('ascii'), item['cwtype'],
                                    cwsource=item['cwsource'], item=item,
                                    raise_on_error=raise_on_error)
         if entity is None:
@@ -220,7 +222,7 @@
 
     def process_relations(self, entity, rels):
         etype = entity.cw_etype
-        for (rtype, role, action), rules in self.source.mapping.get(etype, {}).iteritems():
+        for (rtype, role, action), rules in self.source.mapping.get(etype, {}).items():
             try:
                 related_items = rels[role][rtype]
             except KeyError:
@@ -242,14 +244,14 @@
     def normalize_url(self, url):
         """overridden to add vid=xml if vid is not set in the qs"""
         url = super(CWEntityXMLParser, self).normalize_url(url)
-        purl = urlparse.urlparse(url)
+        purl = urlparse(url)
         if purl.scheme in ('http', 'https'):
-            params = urlparse.parse_qs(purl.query)
+            params = parse_qs(purl.query)
             if 'vid' not in params:
                 params['vid'] = ['xml']
                 purl = list(purl)
-                purl[4] = urllib.urlencode(params, doseq=True)
-                return urlparse.urlunparse(purl)
+                purl[4] = urlencode(params, doseq=True)
+                return urlunparse(purl)
         return url
 
     def complete_url(self, url, etype=None, known_relations=None):
@@ -263,8 +265,8 @@
         If `known_relations` is given, it should be a dictionary of already
         known relations, so they don't get queried again.
         """
-        purl = urlparse.urlparse(url)
-        params = urlparse.parse_qs(purl.query)
+        purl = urlparse(url)
+        params = parse_qs(purl.query)
         if etype is None:
             etype = purl.path.split('/')[-1]
         try:
@@ -277,8 +279,8 @@
                 continue
             relations.add('%s-%s' % (rtype, role))
         purl = list(purl)
-        purl[4] = urllib.urlencode(params, doseq=True)
-        return urlparse.urlunparse(purl)
+        purl[4] = urlencode(params, doseq=True)
+        return urlunparse(purl)
 
     def complete_item(self, item, rels):
         try:
@@ -314,7 +316,7 @@
         """
         node = self.node
         item = dict(node.attrib.items())
-        item['cwtype'] = unicode(node.tag)
+        item['cwtype'] = text_type(node.tag)
         item.setdefault('cwsource', None)
         try:
             item['eid'] = int(item['eid'])
@@ -331,7 +333,7 @@
                 related += self.parser.parse_etree(child)
             elif child.text:
                 # attribute
-                item[child.tag] = unicode(child.text)
+                item[child.tag] = text_type(child.text)
             else:
                 # None attribute (empty tag)
                 item[child.tag] = None
--- a/sobjects/ldapparser.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/sobjects/ldapparser.py	Thu Dec 10 12:34:15 2015 +0100
@@ -1,4 +1,4 @@
-# copyright 2011-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2011-2015 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
 # This file is part of CubicWeb.
@@ -20,12 +20,28 @@
 unlike ldapuser source, this source is copy based and will import ldap content
 (beside passwords for authentication) into the system source.
 """
+from six.moves import map, filter
+
 from logilab.common.decorators import cached, cachedproperty
 from logilab.common.shellutils import generate_password
 
 from cubicweb import Binary, ConfigurationError
 from cubicweb.server.utils import crypt_password
 from cubicweb.server.sources import datafeed
+from cubicweb.dataimport import stores, importer
+
+
+class UserMetaGenerator(stores.MetaGenerator):
+    """Specific metadata generator, used to see newly created user into their initial state.
+    """
+    @cached
+    def base_etype_dicts(self, entity):
+        entity, rels = super(UserMetaGenerator, self).base_etype_dicts(entity)
+        if entity.cw_etype == 'CWUser':
+            wf_state = self._cnx.execute('Any S WHERE ET default_workflow WF, ET name %(etype)s, '
+                                         'WF initial_state S', {'etype': entity.cw_etype}).one()
+            rels['in_state'] = wf_state.eid
+        return entity, rels
 
 
 class DataFeedLDAPAdapter(datafeed.DataFeedParser):
@@ -48,8 +64,8 @@
     def user_source_entities_by_extid(self):
         source = self.source
         if source.user_base_dn.strip():
-            attrs = map(str, source.user_attrs.keys())
-            return dict((userdict['dn'], userdict)
+            attrs = list(map(str, source.user_attrs.keys()))
+            return dict((userdict['dn'].encode('ascii'), userdict)
                         for userdict in source._search(self._cw,
                                                        source.user_base_dn,
                                                        source.user_base_scope,
@@ -61,7 +77,7 @@
     def group_source_entities_by_extid(self):
         source = self.source
         if source.group_base_dn.strip():
-            attrs = map(str, ['modifyTimestamp'] + source.group_attrs.keys())
+            attrs = list(map(str, ['modifyTimestamp'] + list(source.group_attrs.keys())))
             return dict((groupdict['dn'], groupdict)
                         for groupdict in source._search(self._cw,
                                                         source.group_base_dn,
@@ -70,171 +86,170 @@
                                                         attrs))
         return {}
 
-    def _process(self, etype, sdict, raise_on_error=False):
-        self.debug('fetched %s %s', etype, sdict)
-        extid = sdict['dn']
-        entity = self.extid2entity(extid, etype,
-                                   raise_on_error=raise_on_error, **sdict)
-        if entity is not None and not self.created_during_pull(entity):
-            self.notify_updated(entity)
-            attrs = self.ldap2cwattrs(sdict, etype)
-            self.update_if_necessary(entity, attrs)
-            if etype == 'CWUser':
-                self._process_email(entity, sdict)
-            if etype == 'CWGroup':
-                self._process_membership(entity, sdict)
-
     def process(self, url, raise_on_error=False):
         """IDataFeedParser main entry point"""
         self.debug('processing ldapfeed source %s %s', self.source, self.searchfilterstr)
-        for userdict in self.user_source_entities_by_extid.itervalues():
-            self._process('CWUser', userdict)
+        self._group_members = {}
+        eeimporter = self.build_importer(raise_on_error)
+        for name in self.source.user_default_groups:
+            geid = self._get_group(name)
+            eeimporter.extid2eid[geid] = geid
+        entities = self.extentities_generator()
+        set_cwuri = importer.use_extid_as_cwuri(eeimporter.extid2eid)
+        eeimporter.import_entities(set_cwuri(entities))
+        self.stats['created'] = eeimporter.created
+        self.stats['updated'] = eeimporter.updated
+        # handle in_group relation
+        for group, members in self._group_members.items():
+            self._cw.execute('DELETE U in_group G WHERE G name %(g)s', {'g': group})
+            if members:
+                members = ["'%s'" % e for e in members]
+                rql = 'SET U in_group G WHERE G name %%(g)s, U login IN (%s)' % ','.join(members)
+                self._cw.execute(rql, {'g': group})
+        # ensure updated users are activated
+        for eid in eeimporter.updated:
+            entity = self._cw.entity_from_eid(eid)
+            if entity.cw_etype == 'CWUser':
+                self.ensure_activated(entity)
+        # manually set primary email if necessary, it's not handled automatically since hooks are
+        # deactivated
+        self._cw.execute('SET X primary_email E WHERE NOT X primary_email E, X use_email E, '
+                         'X cw_source S, S eid %(s)s, X in_state ST, TS name "activated"',
+                         {'s': self.source.eid})
+
+    def build_importer(self, raise_on_error):
+        """Instantiate and configure an importer"""
+        etypes = ('CWUser', 'EmailAddress', 'CWGroup')
+        extid2eid = importer.cwuri2eid(self._cw, etypes, source_eid=self.source.eid)
+        existing_relations = {}
+        for rtype in ('in_group', 'use_email', 'owned_by'):
+            rql = 'Any S,O WHERE S {} O, S cw_source SO, SO eid %(s)s'.format(rtype)
+            rset = self._cw.execute(rql, {'s': self.source.eid})
+            existing_relations[rtype] = set(tuple(x) for x in rset)
+        return importer.ExtEntitiesImporter(self._cw.vreg.schema, self.build_store(),
+                                            extid2eid=extid2eid,
+                                            existing_relations=existing_relations,
+                                            etypes_order_hint=etypes,
+                                            import_log=self.import_log,
+                                            raise_on_error=raise_on_error)
+
+    def build_store(self):
+        """Instantiate and configure a store"""
+        metagenerator = UserMetaGenerator(self._cw, source=self.source)
+        return stores.NoHookRQLObjectStore(self._cw, metagenerator)
+
+    def extentities_generator(self):
         self.debug('processing ldapfeed source %s %s', self.source, self.searchgroupfilterstr)
-        for groupdict in self.group_source_entities_by_extid.itervalues():
-            self._process('CWGroup', groupdict, raise_on_error=raise_on_error)
+        # generate users and email addresses
+        for userdict in self.user_source_entities_by_extid.values():
+            attrs = self.ldap2cwattrs(userdict, 'CWUser')
+            pwd = attrs.get('upassword')
+            if not pwd:
+                # generate a dumb password if not fetched from ldap (see
+                # userPassword)
+                pwd = crypt_password(generate_password())
+                attrs['upassword'] = set([Binary(pwd)])
+            extuser = importer.ExtEntity('CWUser', userdict['dn'], attrs)
+            extuser.values['owned_by'] = set([extuser.extid])
+            for extemail in self._process_email(extuser, userdict):
+                yield extemail
+            groups = list(filter(None, [self._get_group(name)
+                                        for name in self.source.user_default_groups]))
+            if groups:
+                extuser.values['in_group'] = groups
+            yield extuser
+        # generate groups
+        for groupdict in self.group_source_entities_by_extid.values():
+            attrs = self.ldap2cwattrs(groupdict, 'CWGroup')
+            extgroup = importer.ExtEntity('CWGroup', groupdict['dn'], attrs)
+            yield extgroup
+            # record group membership for later insertion
+            members = groupdict.get(self.source.group_rev_attrs['member'], ())
+            self._group_members[attrs['name']] = members
+
+    def _process_email(self, extuser, userdict):
+        try:
+            emailaddrs = userdict.pop(self.source.user_rev_attrs['email'])
+        except KeyError:
+            return  # no email for that user, nothing to do
+        if not isinstance(emailaddrs, list):
+            emailaddrs = [emailaddrs]
+        for emailaddr in emailaddrs:
+            # search for existing email first, may be coming from another source
+            rset = self._cw.execute('EmailAddress X WHERE X address %(addr)s',
+                                    {'addr': emailaddr})
+            if not rset:
+                # not found, create it. first forge an external id
+                emailextid = userdict['dn'] + '@@' + emailaddr
+                extuser.values.setdefault('use_email', []).append(emailextid)
+                yield importer.ExtEntity('EmailAddress', emailextid, dict(address=[emailaddr]))
+            elif self.sourceuris:
+                # pop from sourceuris anyway, else email may be removed by the
+                # source once import is finished
+                emailextid = userdict['dn'] + '@@' + emailaddr
+                self.sourceuris.pop(emailextid, None)
+            # XXX else check use_email relation?
 
     def handle_deletion(self, config, cnx, myuris):
         if config['delete-entities']:
             super(DataFeedLDAPAdapter, self).handle_deletion(config, cnx, myuris)
             return
         if myuris:
-            byetype = {}
-            for extid, (eid, etype) in myuris.iteritems():
-                if self.is_deleted(extid, etype, eid):
-                    byetype.setdefault(etype, []).append(str(eid))
-
-            for etype, eids in byetype.iteritems():
-                if etype != 'CWUser':
+            for extid, (eid, etype) in myuris.items():
+                if etype != 'CWUser' or not self.is_deleted(extid, etype, eid):
                     continue
-                self.info('deactivate %s %s entities', len(eids), etype)
-                for eid in eids:
-                    wf = cnx.entity_from_eid(eid).cw_adapt_to('IWorkflowable')
-                    wf.fire_transition_if_possible('deactivate')
+                self.info('deactivate user %s', eid)
+                wf = cnx.entity_from_eid(eid).cw_adapt_to('IWorkflowable')
+                wf.fire_transition_if_possible('deactivate')
         cnx.commit()
 
-    def update_if_necessary(self, entity, attrs):
-        # disable read security to allow password selection
-        with entity._cw.security_enabled(read=False):
-            entity.complete(tuple(attrs))
+    def ensure_activated(self, entity):
         if entity.cw_etype == 'CWUser':
             wf = entity.cw_adapt_to('IWorkflowable')
             if wf.state == 'deactivated':
                 wf.fire_transition('activate')
                 self.info('user %s reactivated', entity.login)
-        mdate = attrs.get('modification_date')
-        if not mdate or mdate > entity.modification_date:
-            attrs = dict( (k, v) for k, v in attrs.iteritems()
-                          if v != getattr(entity, k))
-            if attrs:
-                entity.cw_set(**attrs)
-                self.notify_updated(entity)
+
+    def ldap2cwattrs(self, sdict, etype):
+        """Transform dictionary of LDAP attributes to CW.
 
-    def ldap2cwattrs(self, sdict, etype, tdict=None):
-        """ Transform dictionary of LDAP attributes to CW
-        etype must be CWUser or CWGroup """
-        if tdict is None:
-            tdict = {}
+        etype must be CWUser or CWGroup
+        """
+        assert etype in ('CWUser', 'CWGroup'), etype
+        tdict = {}
         if etype == 'CWUser':
-            items = self.source.user_attrs.iteritems()
+            items = self.source.user_attrs.items()
         elif etype == 'CWGroup':
-            items = self.source.group_attrs.iteritems()
+            items = self.source.group_attrs.items()
         for sattr, tattr in items:
             if tattr not in self.non_attribute_keys:
                 try:
-                    tdict[tattr] = sdict[sattr]
+                    value = sdict[sattr]
                 except KeyError:
-                    raise ConfigurationError('source attribute %s has not '
-                                             'been found in the source, '
-                                             'please check the %s-attrs-map '
-                                             'field and the permissions of '
-                                             'the LDAP binding user' %
-                                             (sattr, etype[2:].lower()))
+                    raise ConfigurationError(
+                        'source attribute %s has not been found in the source, '
+                        'please check the %s-attrs-map field and the permissions of '
+                        'the LDAP binding user' % (sattr, etype[2:].lower()))
+                if not isinstance(value, list):
+                    value = [value]
+                tdict[tattr] = value
         return tdict
 
-    def before_entity_copy(self, entity, sourceparams):
-        etype = entity.cw_etype
-        if etype == 'EmailAddress':
-            entity.cw_edited['address'] = sourceparams['address']
-        else:
-            self.ldap2cwattrs(sourceparams, etype, tdict=entity.cw_edited)
-            if etype == 'CWUser':
-                pwd = entity.cw_edited.get('upassword')
-                if not pwd:
-                    # generate a dumb password if not fetched from ldap (see
-                    # userPassword)
-                    pwd = crypt_password(generate_password())
-                    entity.cw_edited['upassword'] = Binary(pwd)
-        return entity
-
-    def after_entity_copy(self, entity, sourceparams):
-        super(DataFeedLDAPAdapter, self).after_entity_copy(entity, sourceparams)
-        etype = entity.cw_etype
-        if etype == 'EmailAddress':
-            return
-        # all CWUsers must be treated before CWGroups to have the in_group relation
-        # set correctly in _associate_ldapusers
-        elif etype == 'CWUser':
-            groups = filter(None, [self._get_group(name)
-                                   for name in self.source.user_default_groups])
-            if groups:
-                entity.cw_set(in_group=groups)
-            self._process_email(entity, sourceparams)
-        elif etype == 'CWGroup':
-            self._process_membership(entity, sourceparams)
-
     def is_deleted(self, extidplus, etype, eid):
         try:
-            extid, _ = extidplus.rsplit('@@', 1)
+            extid = extidplus.rsplit(b'@@', 1)[0]
         except ValueError:
             # for some reason extids here tend to come in both forms, e.g:
             # dn, dn@@Babar
             extid = extidplus
         return extid not in self.user_source_entities_by_extid
 
-    def _process_email(self, entity, userdict):
-        try:
-            emailaddrs = userdict[self.source.user_rev_attrs['email']]
-        except KeyError:
-            return # no email for that user, nothing to do
-        if not isinstance(emailaddrs, list):
-            emailaddrs = [emailaddrs]
-        for emailaddr in emailaddrs:
-            # search for existing email first, may be coming from another source
-            rset = self._cw.execute('EmailAddress X WHERE X address %(addr)s',
-                                   {'addr': emailaddr})
-            if not rset:
-                # not found, create it. first forge an external id
-                emailextid = userdict['dn'] + '@@' + emailaddr.encode('utf-8')
-                email = self.extid2entity(emailextid, 'EmailAddress',
-                                          address=emailaddr)
-                entity.cw_set(use_email=email)
-            elif self.sourceuris:
-                # pop from sourceuris anyway, else email may be removed by the
-                # source once import is finished
-                uri = userdict['dn'] + '@@' + emailaddr.encode('utf-8')
-                self.sourceuris.pop(uri, None)
-            # XXX else check use_email relation?
-
-    def _process_membership(self, entity, sourceparams):
-        """ Find existing CWUsers with the same login as the memberUids in the
-        CWGroup entity and create the in_group relationship """
-        mdate = sourceparams.get('modification_date')
-        if (not mdate or mdate > entity.modification_date):
-            self._cw.execute('DELETE U in_group G WHERE G eid %(g)s',
-                             {'g':entity.eid})
-            members = sourceparams.get(self.source.group_rev_attrs['member'])
-            if members:
-                members = ["'%s'" % e for e in members]
-                rql = 'SET U in_group G WHERE G eid %%(g)s, U login IN (%s)' % ','.join(members)
-                self._cw.execute(rql, {'g':entity.eid,  })
-
     @cached
     def _get_group(self, name):
         try:
             return self._cw.execute('Any X WHERE X is CWGroup, X name %(name)s',
-                                    {'name': name}).get_entity(0, 0)
+                                    {'name': name})[0][0]
         except IndexError:
             self.error('group %r referenced by source configuration %r does not exist',
                        name, self.source.uri)
             return None
-
--- a/sobjects/notification.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/sobjects/notification.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,10 +18,12 @@
 """some views to handle notification on data changes"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from itertools import repeat
 
+from six import text_type
+
 from logilab.common.textutils import normalize_text
 from logilab.common.deprecation import class_renamed, class_moved, deprecated
 from logilab.common.registry import yes
@@ -181,8 +183,8 @@
 
     def context(self, **kwargs):
         entity = self.cw_rset.get_entity(self.cw_row or 0, self.cw_col or 0)
-        for key, val in kwargs.iteritems():
-            if val and isinstance(val, unicode) and val.strip():
+        for key, val in kwargs.items():
+            if val and isinstance(val, text_type) and val.strip():
                kwargs[key] = self._cw._(val)
         kwargs.update({'user': self.user_data['login'],
                        'eid': entity.eid,
@@ -255,7 +257,7 @@
 
 
 def format_value(value):
-    if isinstance(value, unicode):
+    if isinstance(value, text_type):
         return u'"%s"' % value
     return value
 
--- a/sobjects/services.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/sobjects/services.py	Thu Dec 10 12:34:15 2015 +0100
@@ -19,7 +19,10 @@
 
 import threading
 
+from six import text_type
+
 from yams.schema import role_name
+
 from cubicweb import ValidationError
 from cubicweb.server import Service
 from cubicweb.predicates import match_user_groups, match_kwargs
@@ -58,6 +61,7 @@
         results['threads'] = [t.name for t in threading.enumerate()]
         return results
 
+
 class GcStatsService(Service):
     """Return a dictionary containing some statistics about the repository
     resources usage.
@@ -94,9 +98,9 @@
         results = {}
         counters, ocounters, garbage = gc_info(lookupclasses,
                                                viewreferrersclasses=())
-        values = sorted(counters.iteritems(), key=lambda x: x[1], reverse=True)
+        values = sorted(counters.items(), key=lambda x: x[1], reverse=True)
         results['lookupclasses'] = values
-        values = sorted(ocounters.iteritems(), key=lambda x: x[1], reverse=True)[:nmax]
+        values = sorted(ocounters.items(), key=lambda x: x[1], reverse=True)[:nmax]
         results['referenced'] = values
         results['unreachable'] = garbage
         return results
@@ -129,7 +133,7 @@
             qname = role_name('login', 'subject')
             raise ValidationError(None, {qname: errmsg % login})
 
-        if isinstance(password, unicode):
+        if isinstance(password, text_type):
             # password should *always* be utf8 encoded
             password = password.encode('UTF8')
         cwuserkwargs['login'] = login
@@ -154,3 +158,17 @@
                         'WHERE U login %(login)s', d, build_descr=False)
 
         return user
+
+
+class SourceSynchronizationService(Service):
+    """Force synchronization of a datafeed source"""
+    __regid__ = 'source-sync'
+    __select__ = Service.__select__ & match_user_groups('managers')
+
+    def call(self, source_eid):
+        source_entity = self._cw.entity_from_eid(source_eid)
+        repo = self._cw.repo # Service are repo side only.
+        with repo.internal_cnx() as cnx:
+            source = repo.sources_by_uri[source_entity.name]
+            source.pull_data(cnx)
+
--- a/sobjects/supervising.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/sobjects/supervising.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,7 +18,7 @@
 """some hooks and views to handle supervising of any data changes"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from cubicweb import UnknownEid
 from cubicweb.predicates import none_rset
@@ -128,13 +128,15 @@
         # XXX print changes
         self.w(u'  %s' % changedescr.entity.absolute_url())
 
-    def delete_entity(self, (eid, etype, title)):
+    def delete_entity(self, args):
+        eid, etype, title = args
         msg = self._cw._('deleted %(etype)s #%(eid)s (%(title)s)')
         etype = display_name(self._cw, etype).lower()
         self.w(msg % locals())
 
-    def change_state(self, (entity, fromstate, tostate)):
+    def change_state(self, args):
         _ = self._cw._
+        entity, fromstate, tostate = args
         msg = _('changed state of %(etype)s #%(eid)s (%(title)s)')
         self.w(u'%s\n' % (msg % self._entity_context(entity)))
         self.w(_('  from state %(fromstate)s to state %(tostate)s\n' %
--- a/sobjects/test/unittest_cwxmlparser.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/sobjects/test/unittest_cwxmlparser.py	Thu Dec 10 12:34:15 2015 +0100
@@ -17,7 +17,8 @@
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 
 from datetime import datetime
-from urlparse import urlsplit, parse_qsl
+
+from six.moves.urllib.parse import urlsplit, parse_qsl
 
 from cubicweb.devtools.testlib import CubicWebTC
 from cubicweb.sobjects.cwxmlparser import CWEntityXMLParser
@@ -214,8 +215,8 @@
 
         with self.admin_access.web_request() as req:
             user = req.execute('CWUser X WHERE X login "sthenault"').get_entity(0, 0)
-            self.assertEqual(user.creation_date, datetime(2010, 01, 22, 10, 27, 59))
-            self.assertEqual(user.modification_date, datetime(2011, 01, 25, 14, 14, 06))
+            self.assertEqual(user.creation_date, datetime(2010, 1, 22, 10, 27, 59))
+            self.assertEqual(user.modification_date, datetime(2011, 1, 25, 14, 14, 6))
             self.assertEqual(user.cwuri, 'http://pouet.org/5')
             self.assertEqual(user.cw_source[0].name, 'myfeed')
             self.assertEqual(user.absolute_url(), 'http://pouet.org/5')
@@ -299,8 +300,8 @@
         with self.repo.internal_cnx() as cnx:
             stats = dfsource.pull_data(cnx, force=True, raise_on_error=True)
             user = cnx.execute('CWUser X WHERE X login "sthenault"').get_entity(0, 0)
-            self.assertEqual(user.creation_date, datetime(2010, 01, 22, 10, 27, 59))
-            self.assertEqual(user.modification_date, datetime(2011, 01, 25, 14, 14, 06))
+            self.assertEqual(user.creation_date, datetime(2010, 1, 22, 10, 27, 59))
+            self.assertEqual(user.modification_date, datetime(2011, 1, 25, 14, 14, 6))
             self.assertEqual(user.cwuri, 'http://pouet.org/5')
             self.assertEqual(user.cw_source[0].name, 'myfeed')
 
--- a/sobjects/test/unittest_supervising.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/sobjects/test/unittest_supervising.py	Thu Dec 10 12:34:15 2015 +0100
@@ -77,7 +77,7 @@
             # check prepared email
             op._prepare_email()
             self.assertEqual(len(op.to_send), 1)
-            self.assert_(op.to_send[0][0])
+            self.assertTrue(op.to_send[0][0])
             self.assertEqual(op.to_send[0][1], ['test@logilab.fr'])
             cnx.commit()
             # some other changes #######
--- a/spa2rql.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/spa2rql.py	Thu Dec 10 12:34:15 2015 +0100
@@ -146,9 +146,9 @@
 
     def finalize(self):
         """return corresponding rql query (string) / args (dict)"""
-        for varname, ptypes in self.possible_types.iteritems():
+        for varname, ptypes in self.possible_types.items():
             if len(ptypes) == 1:
-                self.restrictions.append('%s is %s' % (varname, iter(ptypes).next()))
+                self.restrictions.append('%s is %s' % (varname, next(iter(ptypes))))
         unions = []
         for releq, subjvar, obj in self.union_params:
             thisunions = []
--- a/tags.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/tags.py	Thu Dec 10 12:34:15 2015 +0100
@@ -59,4 +59,3 @@
     html += options
     html.append(u'</select>')
     return u'\n'.join(html)
-
--- a/test/data/cubes/file/__pkginfo__.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/test/data/cubes/file/__pkginfo__.py	Thu Dec 10 12:34:15 2015 +0100
@@ -23,4 +23,3 @@
 
 numversion = (1, 4, 3)
 version = '.'.join(str(num) for num in numversion)
-
--- a/test/data/rqlexpr_on_computedrel.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/test/data/rqlexpr_on_computedrel.py	Thu Dec 10 12:34:15 2015 +0100
@@ -14,5 +14,3 @@
 class computed(ComputedRelation):
     rule = 'S relation O'
     __permissions__ = {'read': (RRQLExpression('S is ET'),)}
-
-
--- a/test/data/schema.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/test/data/schema.py	Thu Dec 10 12:34:15 2015 +0100
@@ -23,7 +23,7 @@
                              RQLConstraint, RQLVocabularyConstraint)
 
 
-_ = unicode
+from cubicweb import _
 
 
 class Personne(EntityType):
--- a/test/data_schemareader/schema.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/test/data_schemareader/schema.py	Thu Dec 10 12:34:15 2015 +0100
@@ -7,5 +7,3 @@
 cw_for_source.__permissions__ = {'read': ('managers', 'users'),
                                  'add': ('managers',),
                                  'delete': ('managers',)}
-
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/unittest_binary.py	Thu Dec 10 12:34:15 2015 +0100
@@ -0,0 +1,54 @@
+from six import PY2
+
+from unittest import TestCase
+from tempfile import NamedTemporaryFile
+import os.path as osp
+
+from logilab.common.shellutils import tempdir
+from cubicweb import Binary
+
+
+class BinaryTC(TestCase):
+    def test_init(self):
+        Binary()
+        Binary(b'toto')
+        Binary(bytearray(b'toto'))
+        if PY2:
+            Binary(buffer('toto'))
+        else:
+            Binary(memoryview(b'toto'))
+        with self.assertRaises((AssertionError, TypeError)):
+            # TypeError is raised by BytesIO if python runs with -O
+            Binary(u'toto')
+
+    def test_write(self):
+        b = Binary()
+        b.write(b'toto')
+        b.write(bytearray(b'toto'))
+        if PY2:
+            b.write(buffer('toto'))
+        else:
+            b.write(memoryview(b'toto'))
+        with self.assertRaises((AssertionError, TypeError)):
+            # TypeError is raised by BytesIO if python runs with -O
+            b.write(u'toto')
+
+    def test_gzpickle_roundtrip(self):
+        old = (u'foo', b'bar', 42, {})
+        new = Binary.zpickle(old).unzpickle()
+        self.assertEqual(old, new)
+        self.assertIsNot(old, new)
+
+    def test_from_file_to_file(self):
+        with tempdir() as dpath:
+            fpath = osp.join(dpath, 'binary.bin')
+            with open(fpath, 'wb') as fobj:
+                Binary(b'binaryblob').to_file(fobj)
+
+            bobj = Binary.from_file(fpath)
+            self.assertEqual(bobj.getvalue(), b'binaryblob')
+
+
+if __name__ == '__main__':
+    from unittest import main
+    main()
--- a/test/unittest_cwconfig.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/test/unittest_cwconfig.py	Thu Dec 10 12:34:15 2015 +0100
@@ -86,15 +86,6 @@
         finally:
             comment_pkginfo.__recommends_cubes__ = {}
 
-
-#     def test_vc_config(self):
-#         vcconf = self.config.vc_config()
-#         self.assertIsInstance(vcconf['EEMAIL'], Version)
-#         self.assertEqual(vcconf['EEMAIL'], (0, 3, 1))
-#         self.assertEqual(vcconf['CW'], (2, 31, 2))
-#         self.assertRaises(KeyError, vcconf.__getitem__, 'CW_VERSION')
-#         self.assertRaises(KeyError, vcconf.__getitem__, 'CRM')
-
     def test_expand_cubes(self):
         self.config.__class__.CUBES_PATH = [CUSTOM_CUBES_DIR]
         self.config.adjust_sys_path()
--- a/test/unittest_cwctl.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/test/unittest_cwctl.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,7 +18,10 @@
 import sys
 import os
 from os.path import join
-from cStringIO import StringIO
+from io import StringIO, BytesIO
+
+from six import PY2
+
 from logilab.common.testlib import TestCase, unittest_main
 
 from cubicweb.cwconfig import CubicWebConfiguration
@@ -30,7 +33,7 @@
 
 class CubicWebCtlTC(TestCase):
     def setUp(self):
-        self.stream = StringIO()
+        self.stream = BytesIO() if PY2 else StringIO()
         sys.stdout = self.stream
     def tearDown(self):
         sys.stdout = sys.__stdout__
@@ -57,7 +60,7 @@
                                    funcname=None)
             for script, args in scripts.items():
                 scriptname = os.path.join(self.datadir, 'scripts', script)
-                self.assert_(os.path.exists(scriptname))
+                self.assertTrue(os.path.exists(scriptname))
                 mih.cmd_process_script(scriptname, None, scriptargs=args)
 
 
--- a/test/unittest_entity.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/test/unittest_entity.py	Thu Dec 10 12:34:15 2015 +0100
@@ -20,6 +20,8 @@
 
 from datetime import datetime
 
+from six import text_type
+
 from logilab.common import tempattr
 from logilab.common.decorators import clear_cache
 
@@ -644,7 +646,7 @@
 
     def test_printable_value_bytes(self):
         with self.admin_access.web_request() as req:
-            e = req.create_entity('FakeFile', data=Binary('lambda x: 1'), data_format=u'text/x-python',
+            e = req.create_entity('FakeFile', data=Binary(b'lambda x: 1'), data_format=u'text/x-python',
                                   data_encoding=u'ascii', data_name=u'toto.py')
             from cubicweb import mttransforms
             if mttransforms.HAS_PYGMENTS_TRANSFORMS:
@@ -663,8 +665,10 @@
     <span style="color: #C00000;">lambda</span> <span style="color: #000000;">x</span><span style="color: #0000C0;">:</span> <span style="color: #0080C0;">1</span>
 </pre>''')
 
-            e = req.create_entity('FakeFile', data=Binary('*héhéhé*'), data_format=u'text/rest',
-                                data_encoding=u'utf-8', data_name=u'toto.txt')
+            e = req.create_entity('FakeFile',
+                                  data=Binary(u'*héhéhé*'.encode('utf-8')),
+                                  data_format=u'text/rest',
+                                  data_encoding=u'utf-8', data_name=u'toto.txt')
             self.assertEqual(e.printable_value('data'),
                               u'<p><em>héhéhé</em></p>')
 
@@ -717,7 +721,7 @@
             e = self.vreg['etypes'].etype_class('FakeFile')(req)
             e.cw_attr_cache['description'] = 'du <em>html</em>'
             e.cw_attr_cache['description_format'] = 'text/html'
-            e.cw_attr_cache['data'] = Binary('some <em>data</em>')
+            e.cw_attr_cache['data'] = Binary(b'some <em>data</em>')
             e.cw_attr_cache['data_name'] = 'an html file'
             e.cw_attr_cache['data_format'] = 'text/html'
             e.cw_attr_cache['data_encoding'] = 'ascii'
@@ -769,11 +773,11 @@
             # ambiguity test
             person2 = req.create_entity('Personne', prenom=u'remi', nom=u'doe')
             person.cw_clear_all_caches()
-            self.assertEqual(person.rest_path(), unicode(person.eid))
-            self.assertEqual(person2.rest_path(), unicode(person2.eid))
+            self.assertEqual(person.rest_path(), text_type(person.eid))
+            self.assertEqual(person2.rest_path(), text_type(person2.eid))
             # unique attr with None value (nom in this case)
             friend = req.create_entity('Ami', prenom=u'bob')
-            self.assertEqual(friend.rest_path(), unicode(friend.eid))
+            self.assertEqual(friend.rest_path(), text_type(friend.eid))
             # 'ref' below is created without the unique but not required
             # attribute, make sur that the unique _and_ required 'ean' is used
             # as the rest attribute
@@ -853,4 +857,3 @@
 if __name__ == '__main__':
     from logilab.common.testlib import unittest_main
     unittest_main()
-
--- a/test/unittest_mail.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/test/unittest_mail.py	Thu Dec 10 12:34:15 2015 +0100
@@ -149,4 +149,3 @@
 
 if __name__ == '__main__':
     unittest_main()
-
--- a/test/unittest_migration.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/test/unittest_migration.py	Thu Dec 10 12:34:15 2015 +0100
@@ -1,4 +1,4 @@
-# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
 # This file is part of CubicWeb.
@@ -22,7 +22,7 @@
 
 from cubicweb.devtools import TestServerConfiguration
 from cubicweb.cwconfig import CubicWebConfiguration
-from cubicweb.migration import MigrationHelper, filter_scripts
+from cubicweb.migration import MigrationHelper, filter_scripts, version_strictly_lower
 from cubicweb.server.migractions import ServerMigrationHelper
 
 
@@ -76,8 +76,6 @@
     def test_filter_scripts_for_mode(self):
         config = CubicWebConfiguration('data')
         config.verbosity = 0
-        self.assertNotIsInstance(config.migration_handler(), ServerMigrationHelper)
-        self.assertIsInstance(config.migration_handler(), MigrationHelper)
         config = self.config
         config.__class__.name = 'repository'
         self.assertListEqual(filter_scripts(config, TMIGRDIR, (0,0,4), (0,1,0)),
@@ -91,6 +89,10 @@
                                ((0, 1 ,0), TMIGRDIR+'0.1.0_repository.py')])
         config.__class__.name = 'repository'
 
+    def test_version_strictly_lower(self):
+        self.assertTrue(version_strictly_lower(None, '1.0.0'))
+        self.assertFalse(version_strictly_lower('1.0.0', None))
+
 
 from cubicweb.devtools import ApptestConfiguration, get_test_db_handler
 
--- a/test/unittest_predicates.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/test/unittest_predicates.py	Thu Dec 10 12:34:15 2015 +0100
@@ -20,14 +20,17 @@
 from operator import eq, lt, le, gt
 from contextlib import contextmanager
 
+from six.moves import range
+
 from logilab.common.testlib import TestCase, unittest_main
 from logilab.common.decorators import clear_cache
 
 from cubicweb import Binary
 from cubicweb.devtools.testlib import CubicWebTC
 from cubicweb.predicates import (is_instance, adaptable, match_kwargs, match_user_groups,
-                                multi_lines_rset, score_entity, is_in_state,
-                                rql_condition, relation_possible, match_form_params)
+                                 multi_lines_rset, score_entity, is_in_state,
+                                 rql_condition, relation_possible, match_form_params,
+                                 paginated_rset)
 from cubicweb.selectors import on_transition # XXX on_transition is deprecated
 from cubicweb.view import EntityAdapter
 from cubicweb.web import action
@@ -37,7 +40,7 @@
 class ImplementsTC(CubicWebTC):
     def test_etype_priority(self):
         with self.admin_access.web_request() as req:
-            f = req.create_entity('FakeFile', data_name=u'hop.txt', data=Binary('hop'),
+            f = req.create_entity('FakeFile', data_name=u'hop.txt', data=Binary(b'hop'),
                                   data_format=u'text/plain')
             rset = f.as_rset()
             anyscore = is_instance('Any')(f.__class__, req, rset=rset)
@@ -488,6 +491,34 @@
                          "match_form_params() positional arguments must be strings")
 
 
+class PaginatedTC(CubicWebTC):
+    """tests for paginated_rset predicate"""
+
+    def setup_database(self):
+        with self.admin_access.repo_cnx() as cnx:
+            for i in range(30):
+                cnx.create_entity('CWGroup', name=u"group%d" % i)
+            cnx.commit()
+
+    def test_paginated_rset(self):
+        default_nb_pages = 1
+        web_request = self.admin_access.web_request
+        with web_request() as req:
+            rset = req.execute('Any G WHERE G is CWGroup')
+        self.assertEqual(len(rset), 34)
+        with web_request(vid='list', page_size='10') as req:
+            self.assertEqual(paginated_rset()(None, req, rset), default_nb_pages)
+        with web_request(vid='list', page_size='20') as req:
+            self.assertEqual(paginated_rset()(None, req, rset), default_nb_pages)
+        with web_request(vid='list', page_size='50') as req:
+            self.assertEqual(paginated_rset()(None, req, rset), 0)
+        with web_request(vid='list', page_size='10/') as req:
+            self.assertEqual(paginated_rset()(None, req, rset), 0)
+        with web_request(vid='list', page_size='.1') as req:
+            self.assertEqual(paginated_rset()(None, req, rset), 0)
+        with web_request(vid='list', page_size='not_an_int') as req:
+            self.assertEqual(paginated_rset()(None, req, rset), 0)
+
+
 if __name__ == '__main__':
     unittest_main()
-
--- a/test/unittest_rqlrewrite.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/test/unittest_rqlrewrite.py	Thu Dec 10 12:34:15 2015 +0100
@@ -16,6 +16,8 @@
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 
+from six import string_types
+
 from logilab.common.testlib import unittest_main, TestCase
 from logilab.common.testlib import mock_object
 from yams import BadSchemaDefinition
@@ -67,9 +69,9 @@
     rewriter = _prepare_rewriter(rqlrewrite.RQLRewriter, kwargs)
     snippets = []
     for v, exprs in sorted(snippets_map.items()):
-        rqlexprs = [isinstance(snippet, basestring)
-                    and mock_object(snippet_rqlst=parse('Any X WHERE '+snippet).children[0],
-                                    expression='Any X WHERE '+snippet)
+        rqlexprs = [isinstance(snippet, string_types)
+                    and mock_object(snippet_rqlst=parse(u'Any X WHERE '+snippet).children[0],
+                                    expression=u'Any X WHERE '+snippet)
                     or snippet
                     for snippet in exprs]
         snippets.append((dict([v]), rqlexprs))
@@ -90,7 +92,7 @@
             selects.append(stmt)
     assert node in selects, (node, selects)
     for stmt in selects:
-        for var in stmt.defined_vars.itervalues():
+        for var in stmt.defined_vars.values():
             assert var.stinfo['references']
             vrefmap = vrefmaps[stmt]
             assert not (var.stinfo['references'] ^ vrefmap[var.name]), (node.as_string(), var, var.stinfo['references'], vrefmap[var.name])
@@ -108,90 +110,90 @@
     def test_base_var(self):
         constraint = ('X in_state S, U in_group G, P require_state S,'
                            'P name "read", P require_group G')
-        rqlst = parse('Card C')
+        rqlst = parse(u'Card C')
         rewrite(rqlst, {('C', 'X'): (constraint,)}, {})
         self.assertEqual(rqlst.as_string(),
-                         u"Any C WHERE C is Card, B eid %(D)s, "
-                         "EXISTS(C in_state A, B in_group E, F require_state A, "
-                         "F name 'read', F require_group E, A is State, E is CWGroup, F is CWPermission)")
+                         u'Any C WHERE C is Card, B eid %(D)s, '
+                          'EXISTS(C in_state A, B in_group E, F require_state A, '
+                          'F name "read", F require_group E, A is State, E is CWGroup, F is CWPermission)')
 
     def test_multiple_var(self):
         card_constraint = ('X in_state S, U in_group G, P require_state S,'
                            'P name "read", P require_group G')
         affaire_constraints = ('X ref LIKE "PUBLIC%"', 'U in_group G, G name "public"')
         kwargs = {'u':2}
-        rqlst = parse('Any S WHERE S documented_by C, C eid %(u)s')
+        rqlst = parse(u'Any S WHERE S documented_by C, C eid %(u)s')
         rewrite(rqlst, {('C', 'X'): (card_constraint,), ('S', 'X'): affaire_constraints},
                 kwargs)
         self.assertMultiLineEqual(
             rqlst.as_string(),
-            "Any S WHERE S documented_by C, C eid %(u)s, B eid %(D)s, "
-            "EXISTS(C in_state A, B in_group E, F require_state A, "
-            "F name 'read', F require_group E, A is State, E is CWGroup, F is CWPermission), "
-            "(EXISTS(S ref LIKE 'PUBLIC%')) OR (EXISTS(B in_group G, G name 'public', G is CWGroup)), "
-            "S is Affaire")
+            u'Any S WHERE S documented_by C, C eid %(u)s, B eid %(D)s, '
+             'EXISTS(C in_state A, B in_group E, F require_state A, '
+             'F name "read", F require_group E, A is State, E is CWGroup, F is CWPermission), '
+             '(EXISTS(S ref LIKE "PUBLIC%")) OR (EXISTS(B in_group G, G name "public", G is CWGroup)), '
+             'S is Affaire')
         self.assertIn('D', kwargs)
 
     def test_or(self):
         constraint = '(X identity U) OR (X in_state ST, CL identity U, CL in_state ST, ST name "subscribed")'
-        rqlst = parse('Any S WHERE S owned_by C, C eid %(u)s, S is in (CWUser, CWGroup)')
+        rqlst = parse(u'Any S WHERE S owned_by C, C eid %(u)s, S is in (CWUser, CWGroup)')
         rewrite(rqlst, {('C', 'X'): (constraint,)}, {'u':1})
         self.assertEqual(rqlst.as_string(),
-                         "Any S WHERE S owned_by C, C eid %(u)s, S is IN(CWUser, CWGroup), A eid %(B)s, "
-                         "EXISTS((C identity A) OR (C in_state D, E identity A, "
-                         "E in_state D, D name 'subscribed'), D is State, E is CWUser)")
+                         'Any S WHERE S owned_by C, C eid %(u)s, S is IN(CWUser, CWGroup), A eid %(B)s, '
+                         'EXISTS((C identity A) OR (C in_state D, E identity A, '
+                         'E in_state D, D name "subscribed"), D is State, E is CWUser)')
 
     def test_simplified_rqlst(self):
         constraint = ('X in_state S, U in_group G, P require_state S,'
                            'P name "read", P require_group G')
-        rqlst = parse('Any 2') # this is the simplified rql st for Any X WHERE X eid 12
+        rqlst = parse(u'Any 2') # this is the simplified rql st for Any X WHERE X eid 12
         rewrite(rqlst, {('2', 'X'): (constraint,)}, {})
         self.assertEqual(rqlst.as_string(),
-                         u"Any 2 WHERE B eid %(C)s, "
-                         "EXISTS(2 in_state A, B in_group D, E require_state A, "
-                         "E name 'read', E require_group D, A is State, D is CWGroup, E is CWPermission)")
+                         u'Any 2 WHERE B eid %(C)s, '
+                          'EXISTS(2 in_state A, B in_group D, E require_state A, '
+                          'E name "read", E require_group D, A is State, D is CWGroup, E is CWPermission)')
 
     def test_optional_var_1(self):
         constraint = ('X in_state S, U in_group G, P require_state S,'
                            'P name "read", P require_group G')
-        rqlst = parse('Any A,C WHERE A documented_by C?')
+        rqlst = parse(u'Any A,C WHERE A documented_by C?')
         rewrite(rqlst, {('C', 'X'): (constraint,)}, {})
         self.assertEqual(rqlst.as_string(),
-                         "Any A,C WHERE A documented_by C?, A is Affaire "
-                         "WITH C BEING "
-                         "(Any C WHERE EXISTS(C in_state B, D in_group F, G require_state B, G name 'read', "
-                         "G require_group F), D eid %(A)s, C is Card)")
+                         u'Any A,C WHERE A documented_by C?, A is Affaire '
+                          'WITH C BEING '
+                          '(Any C WHERE EXISTS(C in_state B, D in_group F, G require_state B, G name "read", '
+                          'G require_group F), D eid %(A)s, C is Card)')
 
     def test_optional_var_2(self):
         constraint = ('X in_state S, U in_group G, P require_state S,'
                            'P name "read", P require_group G')
-        rqlst = parse('Any A,C,T WHERE A documented_by C?, C title T')
+        rqlst = parse(u'Any A,C,T WHERE A documented_by C?, C title T')
         rewrite(rqlst, {('C', 'X'): (constraint,)}, {})
         self.assertEqual(rqlst.as_string(),
-                         "Any A,C,T WHERE A documented_by C?, A is Affaire "
-                         "WITH C,T BEING "
-                         "(Any C,T WHERE C title T, EXISTS(C in_state B, D in_group F, "
-                         "G require_state B, G name 'read', G require_group F), "
-                         "D eid %(A)s, C is Card)")
+                         u'Any A,C,T WHERE A documented_by C?, A is Affaire '
+                          'WITH C,T BEING '
+                          '(Any C,T WHERE C title T, EXISTS(C in_state B, D in_group F, '
+                          'G require_state B, G name "read", G require_group F), '
+                          'D eid %(A)s, C is Card)')
 
     def test_optional_var_3(self):
         constraint1 = ('X in_state S, U in_group G, P require_state S,'
                        'P name "read", P require_group G')
         constraint2 = 'X in_state S, S name "public"'
-        rqlst = parse('Any A,C,T WHERE A documented_by C?, C title T')
+        rqlst = parse(u'Any A,C,T WHERE A documented_by C?, C title T')
         rewrite(rqlst, {('C', 'X'): (constraint1, constraint2)}, {})
         self.assertEqual(rqlst.as_string(),
-                         "Any A,C,T WHERE A documented_by C?, A is Affaire "
-                         "WITH C,T BEING (Any C,T WHERE C title T, "
-                         "(EXISTS(C in_state B, D in_group F, G require_state B, G name 'read', G require_group F)) "
-                         "OR (EXISTS(C in_state E, E name 'public')), "
-                         "D eid %(A)s, C is Card)")
+                         u'Any A,C,T WHERE A documented_by C?, A is Affaire '
+                          'WITH C,T BEING (Any C,T WHERE C title T, '
+                          '(EXISTS(C in_state B, D in_group F, G require_state B, G name "read", G require_group F)) '
+                          'OR (EXISTS(C in_state E, E name "public")), '
+                          'D eid %(A)s, C is Card)')
 
     def test_optional_var_4(self):
         constraint1 = 'A created_by U, X documented_by A'
         constraint2 = 'A created_by U, X concerne A'
         constraint3 = 'X created_by U'
-        rqlst = parse('Any X,LA,Y WHERE LA? documented_by X, LA concerne Y')
+        rqlst = parse(u'Any X,LA,Y WHERE LA? documented_by X, LA concerne Y')
         rewrite(rqlst, {('LA', 'X'): (constraint1, constraint2),
                         ('X', 'X'): (constraint3,),
                         ('Y', 'X'): (constraint3,)}, {})
@@ -208,7 +210,7 @@
         # see test of the same name in RewriteFullTC: original problem is
         # unreproducible here because it actually lies in
         # RQLRewriter.insert_local_checks
-        rqlst = parse('Any A,AR,X,CD WHERE A concerne X?, A ref AR, A eid %(a)s, X creation_date CD')
+        rqlst = parse(u'Any A,AR,X,CD WHERE A concerne X?, A ref AR, A eid %(a)s, X creation_date CD')
         rewrite(rqlst, {('X', 'X'): ('X created_by U',),}, {'a': 3})
         self.assertEqual(rqlst.as_string(),
                          u'Any A,AR,X,CD WHERE A concerne X?, A ref AR, A eid %(a)s WITH X,CD BEING (Any X,CD WHERE X creation_date CD, EXISTS(X created_by B), B eid %(A)s, X is IN(Division, Note, Societe))')
@@ -216,7 +218,7 @@
     def test_optional_var_inlined(self):
         c1 = ('X require_permission P')
         c2 = ('X inlined_card O, O require_permission P')
-        rqlst = parse('Any C,A,R WHERE A? inlined_card C, A ref R')
+        rqlst = parse(u'Any C,A,R WHERE A? inlined_card C, A ref R')
         rewrite(rqlst, {('C', 'X'): (c1,),
                         ('A', 'X'): (c2,),
                         }, {})
@@ -231,7 +233,7 @@
     # def test_optional_var_inlined_has_perm(self):
     #     c1 = ('X require_permission P')
     #     c2 = ('X inlined_card O, U has_read_permission O')
-    #     rqlst = parse('Any C,A,R WHERE A? inlined_card C, A ref R')
+    #     rqlst = parse(u'Any C,A,R WHERE A? inlined_card C, A ref R')
     #     rewrite(rqlst, {('C', 'X'): (c1,),
     #                     ('A', 'X'): (c2,),
     #                     }, {})
@@ -241,7 +243,7 @@
     def test_optional_var_inlined_imbricated_error(self):
         c1 = ('X require_permission P')
         c2 = ('X inlined_card O, O require_permission P')
-        rqlst = parse('Any C,A,R,A2,R2 WHERE A? inlined_card C, A ref R,A2? inlined_card C, A2 ref R2')
+        rqlst = parse(u'Any C,A,R,A2,R2 WHERE A? inlined_card C, A ref R,A2? inlined_card C, A2 ref R2')
         self.assertRaises(BadSchemaDefinition,
                           rewrite, rqlst, {('C', 'X'): (c1,),
                                            ('A', 'X'): (c2,),
@@ -251,7 +253,7 @@
     def test_optional_var_inlined_linked(self):
         c1 = ('X require_permission P')
         c2 = ('X inlined_card O, O require_permission P')
-        rqlst = parse('Any A,W WHERE A inlined_card C?, C inlined_note N, '
+        rqlst = parse(u'Any A,W WHERE A inlined_card C?, C inlined_note N, '
                       'N inlined_affaire W')
         rewrite(rqlst, {('C', 'X'): (c1,)}, {})
         self.assertEqual(rqlst.as_string(),
@@ -265,70 +267,70 @@
         # relation used in the rql expression can be ignored and S replaced by
         # the variable from the incoming query
         snippet = ('X in_state S, S name "hop"')
-        rqlst = parse('Card C WHERE C in_state STATE')
+        rqlst = parse(u'Card C WHERE C in_state STATE')
         rewrite(rqlst, {('C', 'X'): (snippet,)}, {})
         self.assertEqual(rqlst.as_string(),
-                         "Any C WHERE C in_state STATE, C is Card, "
-                         "EXISTS(STATE name 'hop'), STATE is State")
+                         'Any C WHERE C in_state STATE, C is Card, '
+                         'EXISTS(STATE name "hop"), STATE is State')
 
     def test_relation_optimization_1_rhs(self):
         snippet = ('TW subworkflow_exit X, TW name "hop"')
-        rqlst = parse('WorkflowTransition C WHERE C subworkflow_exit EXIT')
+        rqlst = parse(u'WorkflowTransition C WHERE C subworkflow_exit EXIT')
         rewrite(rqlst, {('EXIT', 'X'): (snippet,)}, {})
         self.assertEqual(rqlst.as_string(),
-                         "Any C WHERE C subworkflow_exit EXIT, C is WorkflowTransition, "
-                         "EXISTS(C name 'hop'), EXIT is SubWorkflowExitPoint")
+                         'Any C WHERE C subworkflow_exit EXIT, C is WorkflowTransition, '
+                         'EXISTS(C name "hop"), EXIT is SubWorkflowExitPoint')
 
     def test_relation_optimization_2_lhs(self):
         # optional relation can be shared if also optional in the snippet
         snippet = ('X in_state S?, S name "hop"')
-        rqlst = parse('Card C WHERE C in_state STATE?')
+        rqlst = parse(u'Card C WHERE C in_state STATE?')
         rewrite(rqlst, {('C', 'X'): (snippet,)}, {})
         self.assertEqual(rqlst.as_string(),
-                         "Any C WHERE C in_state STATE?, C is Card, "
-                         "EXISTS(STATE name 'hop'), STATE is State")
+                         'Any C WHERE C in_state STATE?, C is Card, '
+                         'EXISTS(STATE name "hop"), STATE is State')
     def test_relation_optimization_2_rhs(self):
         snippet = ('TW? subworkflow_exit X, TW name "hop"')
-        rqlst = parse('SubWorkflowExitPoint EXIT WHERE C? subworkflow_exit EXIT')
+        rqlst = parse(u'SubWorkflowExitPoint EXIT WHERE C? subworkflow_exit EXIT')
         rewrite(rqlst, {('EXIT', 'X'): (snippet,)}, {})
         self.assertEqual(rqlst.as_string(),
-                         "Any EXIT WHERE C? subworkflow_exit EXIT, EXIT is SubWorkflowExitPoint, "
-                         "EXISTS(C name 'hop'), C is WorkflowTransition")
+                         'Any EXIT WHERE C? subworkflow_exit EXIT, EXIT is SubWorkflowExitPoint, '
+                         'EXISTS(C name "hop"), C is WorkflowTransition')
 
     def test_relation_optimization_3_lhs(self):
         # optional relation in the snippet but not in the orig tree can be shared
         snippet = ('X in_state S?, S name "hop"')
-        rqlst = parse('Card C WHERE C in_state STATE')
+        rqlst = parse(u'Card C WHERE C in_state STATE')
         rewrite(rqlst, {('C', 'X'): (snippet,)}, {})
         self.assertEqual(rqlst.as_string(),
-                         "Any C WHERE C in_state STATE, C is Card, "
-                         "EXISTS(STATE name 'hop'), STATE is State")
+                         'Any C WHERE C in_state STATE, C is Card, '
+                         'EXISTS(STATE name "hop"), STATE is State')
 
     def test_relation_optimization_3_rhs(self):
         snippet = ('TW? subworkflow_exit X, TW name "hop"')
-        rqlst = parse('WorkflowTransition C WHERE C subworkflow_exit EXIT')
+        rqlst = parse(u'WorkflowTransition C WHERE C subworkflow_exit EXIT')
         rewrite(rqlst, {('EXIT', 'X'): (snippet,)}, {})
         self.assertEqual(rqlst.as_string(),
-                         "Any C WHERE C subworkflow_exit EXIT, C is WorkflowTransition, "
-                         "EXISTS(C name 'hop'), EXIT is SubWorkflowExitPoint")
+                         'Any C WHERE C subworkflow_exit EXIT, C is WorkflowTransition, '
+                         'EXISTS(C name "hop"), EXIT is SubWorkflowExitPoint')
 
     def test_relation_non_optimization_1_lhs(self):
         # but optional relation in the orig tree but not in the snippet can't be shared
         snippet = ('X in_state S, S name "hop"')
-        rqlst = parse('Card C WHERE C in_state STATE?')
+        rqlst = parse(u'Card C WHERE C in_state STATE?')
         rewrite(rqlst, {('C', 'X'): (snippet,)}, {})
         self.assertEqual(rqlst.as_string(),
-                         "Any C WHERE C in_state STATE?, C is Card, "
-                         "EXISTS(C in_state A, A name 'hop', A is State), STATE is State")
+                         'Any C WHERE C in_state STATE?, C is Card, '
+                         'EXISTS(C in_state A, A name "hop", A is State), STATE is State')
 
     def test_relation_non_optimization_1_rhs(self):
         snippet = ('TW subworkflow_exit X, TW name "hop"')
-        rqlst = parse('SubWorkflowExitPoint EXIT WHERE C? subworkflow_exit EXIT')
+        rqlst = parse(u'SubWorkflowExitPoint EXIT WHERE C? subworkflow_exit EXIT')
         rewrite(rqlst, {('EXIT', 'X'): (snippet,)}, {})
         self.assertEqual(rqlst.as_string(),
-                         "Any EXIT WHERE C? subworkflow_exit EXIT, EXIT is SubWorkflowExitPoint, "
-                         "EXISTS(A subworkflow_exit EXIT, A name 'hop', A is WorkflowTransition), "
-                         "C is WorkflowTransition")
+                         'Any EXIT WHERE C? subworkflow_exit EXIT, EXIT is SubWorkflowExitPoint, '
+                         'EXISTS(A subworkflow_exit EXIT, A name "hop", A is WorkflowTransition), '
+                         'C is WorkflowTransition')
 
     def test_relation_non_optimization_2(self):
         """See #3024730"""
@@ -336,7 +338,7 @@
         # previously inserted, else this may introduce duplicated results, as N
         # will then be shared by multiple EXISTS and so at SQL generation time,
         # the table will be in the FROM clause of the outermost query
-        rqlst = parse('Any A,C WHERE A inlined_card C')
+        rqlst = parse(u'Any A,C WHERE A inlined_card C')
         rewrite(rqlst, {('A', 'X'): ('X inlined_card C, C inlined_note N, N owned_by U',),
                         ('C', 'X'): ('X inlined_note N, N owned_by U',)}, {})
         self.assertEqual(rqlst.as_string(),
@@ -348,35 +350,35 @@
     def test_unsupported_constraint_1(self):
         # CWUser doesn't have require_permission
         trinfo_constraint = ('X wf_info_for Y, Y require_permission P, P name "read"')
-        rqlst = parse('Any U,T WHERE U is CWUser, T wf_info_for U')
+        rqlst = parse(u'Any U,T WHERE U is CWUser, T wf_info_for U')
         self.assertRaises(Unauthorized, rewrite, rqlst, {('T', 'X'): (trinfo_constraint,)}, {})
 
     def test_unsupported_constraint_2(self):
         trinfo_constraint = ('X wf_info_for Y, Y require_permission P, P name "read"')
-        rqlst = parse('Any U,T WHERE U is CWUser, T wf_info_for U')
+        rqlst = parse(u'Any U,T WHERE U is CWUser, T wf_info_for U')
         rewrite(rqlst, {('T', 'X'): (trinfo_constraint, 'X wf_info_for Y, Y in_group G, G name "managers"')}, {})
         self.assertEqual(rqlst.as_string(),
-                         u"Any U,T WHERE U is CWUser, T wf_info_for U, "
-                         "EXISTS(U in_group B, B name 'managers', B is CWGroup), T is TrInfo")
+                         u'Any U,T WHERE U is CWUser, T wf_info_for U, '
+                          'EXISTS(U in_group B, B name "managers", B is CWGroup), T is TrInfo')
 
     def test_unsupported_constraint_3(self):
         self.skipTest('raise unauthorized for now')
         trinfo_constraint = ('X wf_info_for Y, Y require_permission P, P name "read"')
-        rqlst = parse('Any T WHERE T wf_info_for X')
+        rqlst = parse(u'Any T WHERE T wf_info_for X')
         rewrite(rqlst, {('T', 'X'): (trinfo_constraint, 'X in_group G, G name "managers"')}, {})
         self.assertEqual(rqlst.as_string(),
                          u'XXX dunno what should be generated')
 
     def test_add_ambiguity_exists(self):
         constraint = ('X concerne Y')
-        rqlst = parse('Affaire X')
+        rqlst = parse(u'Affaire X')
         rewrite(rqlst, {('X', 'X'): (constraint,)}, {})
         self.assertEqual(rqlst.as_string(),
                          u"Any X WHERE X is Affaire, ((EXISTS(X concerne A, A is Division)) OR (EXISTS(X concerne C, C is Societe))) OR (EXISTS(X concerne B, B is Note))")
 
     def test_add_ambiguity_outerjoin(self):
         constraint = ('X concerne Y')
-        rqlst = parse('Any X,C WHERE X? documented_by C')
+        rqlst = parse(u'Any X,C WHERE X? documented_by C')
         rewrite(rqlst, {('X', 'X'): (constraint,)}, {})
         # ambiguity are kept in the sub-query, no need to be resolved using OR
         self.assertEqual(rqlst.as_string(),
@@ -385,76 +387,76 @@
 
     def test_rrqlexpr_nonexistant_subject_1(self):
         constraint = RRQLExpression('S owned_by U')
-        rqlst = parse('Card C')
+        rqlst = parse(u'Card C')
         rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'SU')
         self.assertEqual(rqlst.as_string(),
                          u"Any C WHERE C is Card, A eid %(B)s, EXISTS(C owned_by A)")
-        rqlst = parse('Card C')
+        rqlst = parse(u'Card C')
         rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'OU')
         self.assertEqual(rqlst.as_string(),
                          u"Any C WHERE C is Card")
-        rqlst = parse('Card C')
+        rqlst = parse(u'Card C')
         rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'SOU')
         self.assertEqual(rqlst.as_string(),
                          u"Any C WHERE C is Card, A eid %(B)s, EXISTS(C owned_by A)")
 
     def test_rrqlexpr_nonexistant_subject_2(self):
         constraint = RRQLExpression('S owned_by U, O owned_by U, O is Card')
-        rqlst = parse('Card C')
+        rqlst = parse(u'Card C')
         rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'SU')
         self.assertEqual(rqlst.as_string(),
                          'Any C WHERE C is Card, A eid %(B)s, EXISTS(C owned_by A)')
-        rqlst = parse('Card C')
+        rqlst = parse(u'Card C')
         rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'OU')
         self.assertEqual(rqlst.as_string(),
                          'Any C WHERE C is Card, B eid %(D)s, EXISTS(A owned_by B, A is Card)')
-        rqlst = parse('Card C')
+        rqlst = parse(u'Card C')
         rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'SOU')
         self.assertEqual(rqlst.as_string(),
                          'Any C WHERE C is Card, A eid %(B)s, EXISTS(C owned_by A, D owned_by A, D is Card)')
 
     def test_rrqlexpr_nonexistant_subject_3(self):
         constraint = RRQLExpression('U in_group G, G name "users"')
-        rqlst = parse('Card C')
+        rqlst = parse(u'Card C')
         rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'SU')
         self.assertEqual(rqlst.as_string(),
                          u'Any C WHERE C is Card, A eid %(B)s, EXISTS(A in_group D, D name "users", D is CWGroup)')
 
     def test_rrqlexpr_nonexistant_subject_4(self):
         constraint = RRQLExpression('U in_group G, G name "users", S owned_by U')
-        rqlst = parse('Card C')
+        rqlst = parse(u'Card C')
         rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'SU')
         self.assertEqual(rqlst.as_string(),
                          u'Any C WHERE C is Card, A eid %(B)s, EXISTS(A in_group D, D name "users", C owned_by A, D is CWGroup)')
-        rqlst = parse('Card C')
+        rqlst = parse(u'Card C')
         rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'OU')
         self.assertEqual(rqlst.as_string(),
                          u'Any C WHERE C is Card, A eid %(B)s, EXISTS(A in_group D, D name "users", D is CWGroup)')
 
     def test_rrqlexpr_nonexistant_subject_5(self):
         constraint = RRQLExpression('S owned_by Z, O owned_by Z, O is Card')
-        rqlst = parse('Card C')
+        rqlst = parse(u'Card C')
         rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'S')
         self.assertEqual(rqlst.as_string(),
                          u"Any C WHERE C is Card, EXISTS(C owned_by A, A is CWUser)")
 
     def test_rqlexpr_not_relation_1_1(self):
         constraint = ERQLExpression('X owned_by Z, Z login "hop"', 'X')
-        rqlst = parse('Affaire A WHERE NOT EXISTS(A documented_by C)')
+        rqlst = parse(u'Affaire A WHERE NOT EXISTS(A documented_by C)')
         rewrite(rqlst, {('C', 'X'): (constraint,)}, {}, 'X')
         self.assertEqual(rqlst.as_string(),
                          u'Any A WHERE NOT EXISTS(A documented_by C, EXISTS(C owned_by B, B login "hop", B is CWUser), C is Card), A is Affaire')
 
     def test_rqlexpr_not_relation_1_2(self):
         constraint = ERQLExpression('X owned_by Z, Z login "hop"', 'X')
-        rqlst = parse('Affaire A WHERE NOT EXISTS(A documented_by C)')
+        rqlst = parse(u'Affaire A WHERE NOT EXISTS(A documented_by C)')
         rewrite(rqlst, {('A', 'X'): (constraint,)}, {}, 'X')
         self.assertEqual(rqlst.as_string(),
                          u'Any A WHERE NOT EXISTS(A documented_by C, C is Card), A is Affaire, EXISTS(A owned_by B, B login "hop", B is CWUser)')
 
     def test_rqlexpr_not_relation_2(self):
         constraint = ERQLExpression('X owned_by Z, Z login "hop"', 'X')
-        rqlst = rqlhelper.parse('Affaire A WHERE NOT A documented_by C', annotate=False)
+        rqlst = rqlhelper.parse(u'Affaire A WHERE NOT A documented_by C', annotate=False)
         rewrite(rqlst, {('C', 'X'): (constraint,)}, {}, 'X')
         self.assertEqual(rqlst.as_string(),
                          u'Any A WHERE NOT EXISTS(A documented_by C, EXISTS(C owned_by B, B login "hop", B is CWUser), C is Card), A is Affaire')
@@ -463,7 +465,7 @@
         c1 = ERQLExpression('X owned_by Z, Z login "hop"', 'X')
         c2 = ERQLExpression('X owned_by Z, Z login "hip"', 'X')
         c3 = ERQLExpression('X owned_by Z, Z login "momo"', 'X')
-        rqlst = rqlhelper.parse('Any A WHERE A documented_by C?', annotate=False)
+        rqlst = rqlhelper.parse(u'Any A WHERE A documented_by C?', annotate=False)
         rewrite(rqlst, {('C', 'X'): (c1, c2, c3)}, {}, 'X')
         self.assertEqual(rqlst.as_string(),
                          u'Any A WHERE A documented_by C?, A is Affaire '
@@ -484,12 +486,12 @@
         # 4. this variable require a rewrite
         c_bad = ERQLExpression('X documented_by R, A in_state R')
 
-        rqlst = parse('Any A, R WHERE A ref R, S is Affaire')
+        rqlst = parse(u'Any A, R WHERE A ref R, S is Affaire')
         rewrite(rqlst, {('A', 'X'): (c_ok, c_bad)}, {})
 
     def test_nonregr_is_instance_of(self):
         user_expr = ERQLExpression('NOT X in_group AF, AF name "guests"')
-        rqlst = parse('Any O WHERE S use_email O, S is CWUser, O is_instance_of EmailAddress')
+        rqlst = parse(u'Any O WHERE S use_email O, S is CWUser, O is_instance_of EmailAddress')
         rewrite(rqlst, {('S', 'X'): (user_expr,)}, {})
         self.assertEqual(rqlst.as_string(),
                          'Any O WHERE S use_email O, S is CWUser, O is EmailAddress, '
@@ -600,7 +602,7 @@
     # Basic tests
     def test_base_rule(self):
         rules = {'participated_in': 'S contributor O'}
-        rqlst = rqlhelper.parse('Any X WHERE X participated_in S')
+        rqlst = rqlhelper.parse(u'Any X WHERE X participated_in S')
         rule_rewrite(rqlst, rules)
         self.assertEqual('Any X WHERE X contributor S',
                          rqlst.as_string())
@@ -609,7 +611,7 @@
         rules = {'illustrator_of': ('C is Contribution, C contributor S, '
                                     'C manifestation O, C role R, '
                                     'R name "illustrator"')}
-        rqlst = rqlhelper.parse('Any A,B WHERE A illustrator_of B')
+        rqlst = rqlhelper.parse(u'Any A,B WHERE A illustrator_of B')
         rule_rewrite(rqlst, rules)
         self.assertEqual('Any A,B WHERE C is Contribution, '
                          'C contributor A, C manifestation B, '
@@ -620,7 +622,7 @@
         rules = {'illustrator_of': ('C is Contribution, C contributor S, '
                                     'C manifestation O, C role R, '
                                     'R name "illustrator"')}
-        rqlst = rqlhelper.parse('Any A WHERE EXISTS(A illustrator_of B)')
+        rqlst = rqlhelper.parse(u'Any A WHERE EXISTS(A illustrator_of B)')
         rule_rewrite(rqlst, rules)
         self.assertEqual('Any A WHERE EXISTS(C is Contribution, '
                          'C contributor A, C manifestation B, '
@@ -631,7 +633,7 @@
     def test_rewrite2(self):
         rules = {'illustrator_of': 'C is Contribution, C contributor S, '
                 'C manifestation O, C role R, R name "illustrator"'}
-        rqlst = rqlhelper.parse('Any A,B WHERE A illustrator_of B, C require_permission R, S'
+        rqlst = rqlhelper.parse(u'Any A,B WHERE A illustrator_of B, C require_permission R, S'
                                 'require_state O')
         rule_rewrite(rqlst, rules)
         self.assertEqual('Any A,B WHERE C require_permission R, S require_state O, '
@@ -642,7 +644,7 @@
     def test_rewrite3(self):
         rules = {'illustrator_of': 'C is Contribution, C contributor S, '
                 'C manifestation O, C role R, R name "illustrator"'}
-        rqlst = rqlhelper.parse('Any A,B WHERE E require_permission T, A illustrator_of B')
+        rqlst = rqlhelper.parse(u'Any A,B WHERE E require_permission T, A illustrator_of B')
         rule_rewrite(rqlst, rules)
         self.assertEqual('Any A,B WHERE E require_permission T, '
                          'C is Contribution, C contributor A, C manifestation B, '
@@ -652,7 +654,7 @@
     def test_rewrite4(self):
         rules = {'illustrator_of': 'C is Contribution, C contributor S, '
                 'C manifestation O, C role R, R name "illustrator"'}
-        rqlst = rqlhelper.parse('Any A,B WHERE C require_permission R, A illustrator_of B')
+        rqlst = rqlhelper.parse(u'Any A,B WHERE C require_permission R, A illustrator_of B')
         rule_rewrite(rqlst, rules)
         self.assertEqual('Any A,B WHERE C require_permission R, '
                          'D is Contribution, D contributor A, D manifestation B, '
@@ -662,7 +664,7 @@
     def test_rewrite5(self):
         rules = {'illustrator_of': 'C is Contribution, C contributor S, '
                 'C manifestation O, C role R, R name "illustrator"'}
-        rqlst = rqlhelper.parse('Any A,B WHERE C require_permission R, A illustrator_of B, '
+        rqlst = rqlhelper.parse(u'Any A,B WHERE C require_permission R, A illustrator_of B, '
                                 'S require_state O')
         rule_rewrite(rqlst, rules)
         self.assertEqual('Any A,B WHERE C require_permission R, S require_state O, '
@@ -674,7 +676,7 @@
     def test_rewrite_with(self):
         rules = {'illustrator_of': 'C is Contribution, C contributor S, '
                 'C manifestation O, C role R, R name "illustrator"'}
-        rqlst = rqlhelper.parse('Any A,B WITH A, B BEING(Any X, Y WHERE X illustrator_of Y)')
+        rqlst = rqlhelper.parse(u'Any A,B WITH A, B BEING(Any X, Y WHERE X illustrator_of Y)')
         rule_rewrite(rqlst, rules)
         self.assertEqual('Any A,B WITH A,B BEING '
                          '(Any X,Y WHERE A is Contribution, A contributor X, '
@@ -684,7 +686,7 @@
     def test_rewrite_with2(self):
         rules = {'illustrator_of': 'C is Contribution, C contributor S, '
                 'C manifestation O, C role R, R name "illustrator"'}
-        rqlst = rqlhelper.parse('Any A,B WHERE T require_permission C WITH A, B BEING(Any X, Y WHERE X illustrator_of Y)')
+        rqlst = rqlhelper.parse(u'Any A,B WHERE T require_permission C WITH A, B BEING(Any X, Y WHERE X illustrator_of Y)')
         rule_rewrite(rqlst, rules)
         self.assertEqual('Any A,B WHERE T require_permission C '
                          'WITH A,B BEING (Any X,Y WHERE A is Contribution, '
@@ -693,7 +695,7 @@
 
     def test_rewrite_with3(self):
         rules = {'participated_in': 'S contributor O'}
-        rqlst = rqlhelper.parse('Any A,B WHERE A participated_in B '
+        rqlst = rqlhelper.parse(u'Any A,B WHERE A participated_in B '
                                 'WITH A, B BEING(Any X,Y WHERE X contributor Y)')
         rule_rewrite(rqlst, rules)
         self.assertEqual('Any A,B WHERE A contributor B WITH A,B BEING '
@@ -703,7 +705,7 @@
     def test_rewrite_with4(self):
         rules = {'illustrator_of': 'C is Contribution, C contributor S, '
                 'C manifestation O, C role R, R name "illustrator"'}
-        rqlst = rqlhelper.parse('Any A,B WHERE A illustrator_of B '
+        rqlst = rqlhelper.parse(u'Any A,B WHERE A illustrator_of B '
                                'WITH A, B BEING(Any X, Y WHERE X illustrator_of Y)')
         rule_rewrite(rqlst, rules)
         self.assertEqual('Any A,B WHERE C is Contribution, '
@@ -717,7 +719,7 @@
     def test_rewrite_union(self):
         rules = {'illustrator_of': 'C is Contribution, C contributor S, '
                 'C manifestation O, C role R, R name "illustrator"'}
-        rqlst = rqlhelper.parse('(Any A,B WHERE A illustrator_of B) UNION'
+        rqlst = rqlhelper.parse(u'(Any A,B WHERE A illustrator_of B) UNION'
                                 '(Any X,Y WHERE X is CWUser, Z manifestation Y)')
         rule_rewrite(rqlst, rules)
         self.assertEqual('(Any A,B WHERE C is Contribution, '
@@ -728,7 +730,7 @@
     def test_rewrite_union2(self):
         rules = {'illustrator_of': 'C is Contribution, C contributor S, '
                 'C manifestation O, C role R, R name "illustrator"'}
-        rqlst = rqlhelper.parse('(Any Y WHERE Y match W) UNION '
+        rqlst = rqlhelper.parse(u'(Any Y WHERE Y match W) UNION '
                                 '(Any A WHERE A illustrator_of B) UNION '
                                 '(Any Y WHERE Y is ArtWork)')
         rule_rewrite(rqlst, rules)
@@ -742,7 +744,7 @@
     def test_rewrite_exists(self):
         rules = {'illustrator_of': 'C is Contribution, C contributor S, '
                 'C manifestation O, C role R, R name "illustrator"'}
-        rqlst = rqlhelper.parse('(Any A,B WHERE A illustrator_of B, '
+        rqlst = rqlhelper.parse(u'(Any A,B WHERE A illustrator_of B, '
                      'EXISTS(B is ArtWork))')
         rule_rewrite(rqlst, rules)
         self.assertEqual('Any A,B WHERE EXISTS(B is ArtWork), '
@@ -753,7 +755,7 @@
     def test_rewrite_exists2(self):
         rules = {'illustrator_of': 'C is Contribution, C contributor S, '
                 'C manifestation O, C role R, R name "illustrator"'}
-        rqlst = rqlhelper.parse('(Any A,B WHERE B contributor A, EXISTS(A illustrator_of W))')
+        rqlst = rqlhelper.parse(u'(Any A,B WHERE B contributor A, EXISTS(A illustrator_of W))')
         rule_rewrite(rqlst, rules)
         self.assertEqual('Any A,B WHERE B contributor A, '
                          'EXISTS(C is Contribution, C contributor A, C manifestation W, '
@@ -763,7 +765,7 @@
     def test_rewrite_exists3(self):
         rules = {'illustrator_of': 'C is Contribution, C contributor S, '
                 'C manifestation O, C role R, R name "illustrator"'}
-        rqlst = rqlhelper.parse('(Any A,B WHERE A illustrator_of B, EXISTS(A illustrator_of W))')
+        rqlst = rqlhelper.parse(u'(Any A,B WHERE A illustrator_of B, EXISTS(A illustrator_of W))')
         rule_rewrite(rqlst, rules)
         self.assertEqual('Any A,B WHERE EXISTS(C is Contribution, C contributor A, '
                          'C manifestation W, C role D, D name "illustrator"), '
@@ -774,7 +776,7 @@
     # Test for GROUPBY
     def test_rewrite_groupby(self):
         rules = {'participated_in': 'S contributor O'}
-        rqlst = rqlhelper.parse('Any SUM(SA) GROUPBY S WHERE P participated_in S, P manifestation SA')
+        rqlst = rqlhelper.parse(u'Any SUM(SA) GROUPBY S WHERE P participated_in S, P manifestation SA')
         rule_rewrite(rqlst, rules)
         self.assertEqual('Any SUM(SA) GROUPBY S WHERE P manifestation SA, P contributor S',
                          rqlst.as_string())
--- a/test/unittest_rset.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/test/unittest_rset.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,8 +18,9 @@
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """unit tests for module cubicweb.utils"""
 
-from urlparse import urlsplit
-import pickle
+from six import string_types
+from six.moves import cPickle as pickle
+from six.moves.urllib.parse import urlsplit
 
 from rql import parse
 
@@ -100,7 +101,11 @@
 
     def test_pickle(self):
         del self.rset.req
-        self.assertEqual(len(pickle.dumps(self.rset)), 376)
+        rs2 = pickle.loads(pickle.dumps(self.rset))
+        self.assertEqual(self.rset.rows, rs2.rows)
+        self.assertEqual(self.rset.rowcount, rs2.rowcount)
+        self.assertEqual(self.rset.rql, rs2.rql)
+        self.assertEqual(self.rset.description, rs2.description)
 
     def test_build_url(self):
         with self.admin_access.web_request() as req:
@@ -274,7 +279,7 @@
         """make sure syntax tree is cached"""
         rqlst1 = self.rset.syntax_tree()
         rqlst2 = self.rset.syntax_tree()
-        self.assert_(rqlst1 is rqlst2)
+        self.assertIs(rqlst1, rqlst2)
 
     def test_get_entity_simple(self):
         with self.admin_access.web_request() as req:
@@ -550,19 +555,32 @@
     def test_str(self):
         with self.admin_access.web_request() as req:
             rset = req.execute('(Any X,N WHERE X is CWGroup, X name N)')
-            self.assertIsInstance(str(rset), basestring)
+            self.assertIsInstance(str(rset), string_types)
             self.assertEqual(len(str(rset).splitlines()), 1)
 
     def test_repr(self):
         with self.admin_access.web_request() as req:
             rset = req.execute('(Any X,N WHERE X is CWGroup, X name N)')
-            self.assertIsInstance(repr(rset), basestring)
+            self.assertIsInstance(repr(rset), string_types)
             self.assertTrue(len(repr(rset).splitlines()) > 1)
 
             rset = req.execute('(Any X WHERE X is CWGroup, X name "managers")')
-            self.assertIsInstance(str(rset), basestring)
+            self.assertIsInstance(str(rset), string_types)
             self.assertEqual(len(str(rset).splitlines()), 1)
 
+    def test_slice(self):
+        rs = ResultSet([[12000, 'adim', u'Adim chez les pinguins'],
+                        [12000, 'adim', u'Jardiner facile'],
+                        [13000, 'syt',  u'Le carrelage en 42 leçons'],
+                        [14000, 'nico', u'La tarte tatin en 15 minutes'],
+                        [14000, 'nico', u"L'épluchage du castor commun"]],
+                       'Any U, L, T WHERE U is CWUser, U login L,'\
+                       'D created_by U, D title T',
+                       description=[['CWUser', 'String', 'String']] * 5)
+        self.assertEqual(rs[1::2],
+            [[12000, 'adim', u'Jardiner facile'],
+             [14000, 'nico', u'La tarte tatin en 15 minutes']])
+
     def test_nonregr_symmetric_relation(self):
         # see https://www.cubicweb.org/ticket/4739253
         with self.admin_access.client_cnx() as cnx:
--- a/test/unittest_schema.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/test/unittest_schema.py	Thu Dec 10 12:34:15 2015 +0100
@@ -105,10 +105,9 @@
         #
         # isinstance(cstr, RQLConstraint)
         # -> expected to return RQLConstraint instances but not
-        #    RRQLVocabularyConstraint and QLUniqueConstraint
+        #    RQLVocabularyConstraint and RQLUniqueConstraint
         self.assertFalse(issubclass(RQLUniqueConstraint, RQLVocabularyConstraint))
         self.assertFalse(issubclass(RQLUniqueConstraint, RQLConstraint))
-        self.assertTrue(issubclass(RQLConstraint, RQLVocabularyConstraint))
 
     def test_entity_perms(self):
         self.assertEqual(eperson.get_groups('read'), set(('managers', 'users', 'guests')))
@@ -158,7 +157,7 @@
 
     def test_knownValues_load_schema(self):
         schema = loader.load(config)
-        self.assert_(isinstance(schema, CubicWebSchema))
+        self.assertIsInstance(schema, CubicWebSchema)
         self.assertEqual(schema.name, 'data')
         entities = sorted([str(e) for e in schema.entities()])
         expected_entities = ['Ami', 'BaseTransition', 'BigInt', 'Bookmark', 'Boolean', 'Bytes', 'Card',
@@ -273,11 +272,13 @@
         config = TestConfiguration('data', apphome=join(dirname(__file__), 'data_schemareader'))
         config.bootstrap_cubes()
         schema = loader.load(config)
-        self.assertEqual(schema['in_group'].rdefs.values()[0].permissions,
+        rdef = next(iter(schema['in_group'].rdefs.values()))
+        self.assertEqual(rdef.permissions,
                          {'read': ('managers',),
                           'add': ('managers',),
                           'delete': ('managers',)})
-        self.assertEqual(schema['cw_for_source'].rdefs.values()[0].permissions,
+        rdef = next(iter(schema['cw_for_source'].rdefs.values()))
+        self.assertEqual(rdef.permissions,
                          {'read': ('managers', 'users'),
                           'add': ('managers',),
                           'delete': ('managers',)})
@@ -355,11 +356,11 @@
 
         # check object/subject type
         self.assertEqual([('Person','Service')],
-                         schema['produces_and_buys'].rdefs.keys())
+                         list(schema['produces_and_buys'].rdefs.keys()))
         self.assertEqual([('Person','Service')],
-                         schema['produces_and_buys2'].rdefs.keys())
+                         list(schema['produces_and_buys2'].rdefs.keys()))
         self.assertCountEqual([('Company', 'Service'), ('Person', 'Service')],
-                              schema['reproduce'].rdefs.keys())
+                              list(schema['reproduce'].rdefs.keys()))
         # check relation definitions are marked infered
         rdef = schema['produces_and_buys'].rdefs[('Person','Service')]
         self.assertTrue(rdef.infered)
@@ -426,7 +427,9 @@
 
     def test(self):
         self.assertEqual(normalize_expression('X  bla Y,Y blur Z  ,  Z zigoulou   X '),
-                                               'X bla Y, Y blur Z, Z zigoulou X')
+                                              'X bla Y, Y blur Z, Z zigoulou X')
+        self.assertEqual(normalize_expression('X bla Y, Y name "x,y"'),
+                                              'X bla Y, Y name "x,y"')
 
 
 class RQLExpressionTC(TestCase):
@@ -553,7 +556,7 @@
             self.set_description('composite rdefs for %s' % etype)
             yield self.assertEqual, self.composites[etype], \
                              sorted([(r.rtype.type, r.subject.type, r.object.type, role)
-                                     for r, role in sorted(schema[etype].composite_rdef_roles)])
+                                     for r, role in schema[etype].composite_rdef_roles])
 
 
 if __name__ == '__main__':
--- a/test/unittest_uilib.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/test/unittest_uilib.py	Thu Dec 10 12:34:15 2015 +0100
@@ -200,4 +200,3 @@
 
 if __name__ == '__main__':
     unittest_main()
-
--- a/test/unittest_utils.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/test/unittest_utils.py	Thu Dec 10 12:34:15 2015 +0100
@@ -21,12 +21,13 @@
 import decimal
 import datetime
 
+from six.moves import range
 
 from logilab.common.testlib import TestCase, DocTest, unittest_main
 
 from cubicweb.devtools.testlib import CubicWebTC
-from cubicweb.utils import (make_uid, UStringIO, SizeConstrainedList,
-                            RepeatList, HTMLHead, QueryCache, parse_repo_uri)
+from cubicweb.utils import (make_uid, UStringIO, RepeatList, HTMLHead,
+                            QueryCache, parse_repo_uri)
 from cubicweb.entity import Entity
 
 try:
@@ -67,7 +68,7 @@
     def test_querycache(self):
         c = QueryCache(ceiling=20)
         # write only
-        for x in xrange(10):
+        for x in range(10):
             c[x] = x
         self.assertEqual(c._usage_report(),
                          {'transientcount': 0,
@@ -75,7 +76,7 @@
                           'permanentcount': 0})
         c = QueryCache(ceiling=10)
         # we should also get a warning
-        for x in xrange(20):
+        for x in range(20):
             c[x] = x
         self.assertEqual(c._usage_report(),
                          {'transientcount': 0,
@@ -83,8 +84,8 @@
                           'permanentcount': 0})
         # write + reads
         c = QueryCache(ceiling=20)
-        for n in xrange(4):
-            for x in xrange(10):
+        for n in range(4):
+            for x in range(10):
                 c[x] = x
                 c[x]
         self.assertEqual(c._usage_report(),
@@ -92,8 +93,8 @@
                           'itemcount': 10,
                           'permanentcount': 0})
         c = QueryCache(ceiling=20)
-        for n in xrange(17):
-            for x in xrange(10):
+        for n in range(17):
+            for x in range(10):
                 c[x] = x
                 c[x]
         self.assertEqual(c._usage_report(),
@@ -101,8 +102,8 @@
                           'itemcount': 10,
                           'permanentcount': 10})
         c = QueryCache(ceiling=20)
-        for n in xrange(17):
-            for x in xrange(10):
+        for n in range(17):
+            for x in range(10):
                 c[x] = x
                 if n % 2:
                     c[x]
@@ -115,7 +116,7 @@
 
 class UStringIOTC(TestCase):
     def test_boolean_value(self):
-        self.assert_(UStringIO())
+        self.assertTrue(UStringIO())
 
 
 class RepeatListTC(TestCase):
@@ -165,25 +166,6 @@
         self.assertEqual(l, [(1, 3)]*2)
 
 
-class SizeConstrainedListTC(TestCase):
-
-    def test_append(self):
-        l = SizeConstrainedList(10)
-        for i in xrange(12):
-            l.append(i)
-        self.assertEqual(l, range(2, 12))
-
-    def test_extend(self):
-        testdata = [(range(5), range(5)),
-                    (range(10), range(10)),
-                    (range(12), range(2, 12)),
-                    ]
-        for extension, expected in testdata:
-            l = SizeConstrainedList(10)
-            l.extend(extension)
-            yield self.assertEqual, l, expected
-
-
 class JSONEncoderTC(TestCase):
     def setUp(self):
         if json is None:
--- a/toolsutils.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/toolsutils.py	Thu Dec 10 12:34:15 2015 +0100
@@ -16,6 +16,7 @@
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """some utilities for cubicweb command line tools"""
+from __future__ import print_function
 
 __docformat__ = "restructuredtext en"
 
@@ -37,6 +38,8 @@
     def symlink(*args):
         raise NotImplementedError
 
+from six import add_metaclass
+
 from logilab.common.clcommands import Command as BaseCommand
 from logilab.common.shellutils import ASK
 
@@ -62,29 +65,29 @@
     """create a directory if it doesn't exist yet"""
     try:
         makedirs(directory)
-        print '-> created directory %s' % directory
+        print('-> created directory %s' % directory)
     except OSError as ex:
         import errno
         if ex.errno != errno.EEXIST:
             raise
-        print '-> no need to create existing directory %s' % directory
+        print('-> no need to create existing directory %s' % directory)
 
 def create_symlink(source, target):
     """create a symbolic link"""
     if exists(target):
         remove(target)
     symlink(source, target)
-    print '[symlink] %s <-- %s' % (target, source)
+    print('[symlink] %s <-- %s' % (target, source))
 
 def create_copy(source, target):
     import shutil
-    print '[copy] %s <-- %s' % (target, source)
+    print('[copy] %s <-- %s' % (target, source))
     shutil.copy2(source, target)
 
 def rm(whatever):
     import shutil
     shutil.rmtree(whatever)
-    print '-> removed %s' % whatever
+    print('-> removed %s' % whatever)
 
 def show_diffs(appl_file, ref_file, askconfirm=True):
     """interactivly replace the old file with the new file according to
@@ -95,8 +98,8 @@
     diffs = pipe.stdout.read()
     if diffs:
         if askconfirm:
-            print
-            print diffs
+            print()
+            print(diffs)
             action = ASK.ask('Replace ?', ('Y', 'n', 'q'), 'Y').lower()
         else:
             action = 'y'
@@ -106,17 +109,17 @@
             except IOError:
                 os.system('chmod a+w %s' % appl_file)
                 shutil.copyfile(ref_file, appl_file)
-            print 'replaced'
+            print('replaced')
         elif action == 'q':
             sys.exit(0)
         else:
             copy_file = appl_file + '.default'
-            copy = file(copy_file, 'w')
+            copy = open(copy_file, 'w')
             copy.write(open(ref_file).read())
             copy.close()
-            print 'keep current version, the new file has been written to', copy_file
+            print('keep current version, the new file has been written to', copy_file)
     else:
-        print 'no diff between %s and %s' % (appl_file, ref_file)
+        print('no diff between %s and %s' % (appl_file, ref_file))
 
 SKEL_EXCLUDE = ('*.py[co]', '*.orig', '*~', '*_flymake.py')
 def copy_skeleton(skeldir, targetdir, context,
@@ -143,15 +146,15 @@
                 if not askconfirm or not exists(tfpath) or \
                        ASK.confirm('%s exists, overwrite?' % tfpath):
                     fill_templated_file(fpath, tfpath, context)
-                    print '[generate] %s <-- %s' % (tfpath, fpath)
+                    print('[generate] %s <-- %s' % (tfpath, fpath))
             elif exists(tfpath):
                 show_diffs(tfpath, fpath, askconfirm)
             else:
                 shutil.copyfile(fpath, tfpath)
 
 def fill_templated_file(fpath, tfpath, context):
-    fobj = file(tfpath, 'w')
-    templated = file(fpath).read()
+    fobj = open(tfpath, 'w')
+    templated = open(fpath).read()
     fobj.write(templated % context)
     fobj.close()
 
@@ -160,8 +163,8 @@
     if log:
         log('set permissions to 0600 for %s', filepath)
     else:
-        print '-> set permissions to 0600 for %s' % filepath
-    chmod(filepath, 0600)
+        print('-> set permissions to 0600 for %s' % filepath)
+    chmod(filepath, 0o600)
 
 def read_config(config_file, raise_if_unreadable=False):
     """read some simple configuration from `config_file` and return it as a
@@ -209,12 +212,13 @@
         return cls
 
 
+@add_metaclass(metacmdhandler)
 class CommandHandler(object):
     """configuration specific helper for cubicweb-ctl commands"""
-    __metaclass__ = metacmdhandler
     def __init__(self, config):
         self.config = config
 
+
 class Command(BaseCommand):
     """base class for cubicweb-ctl commands"""
 
@@ -234,7 +238,7 @@
             raise ConfigurationError(msg)
 
     def fail(self, reason):
-        print "command failed:", reason
+        print("command failed:", reason)
         sys.exit(1)
 
 
--- a/tox.ini	Wed Dec 09 18:42:13 2015 +0100
+++ b/tox.ini	Thu Dec 10 12:34:15 2015 +0100
@@ -8,7 +8,9 @@
 [testenv:cubicweb]
 deps =
   -r{toxinidir}/test/requirements.txt
-commands = pytest -t test {posargs}
+commands =
+  {envpython} -m pip install --upgrade --no-deps --quiet git+git://github.com/logilab/yapps@master#egg=yapps
+  pytest -t test {posargs}
 
 [testenv:dataimport]
 
@@ -29,6 +31,8 @@
   -r{toxinidir}/ext/test/requirements.txt
 
 [testenv:hooks]
+deps =
+  -r{toxinidir}/hooks/test/requirements.txt
 
 [testenv:server]
 deps =
--- a/transaction.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/transaction.py	Thu Dec 10 12:34:15 2015 +0100
@@ -17,7 +17,7 @@
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """ undoable transaction objects. """
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from cubicweb import RepositoryError
 
--- a/uilib.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/uilib.py	Thu Dec 10 12:34:15 2015 +0100
@@ -26,12 +26,15 @@
 
 import csv
 import re
-from StringIO import StringIO
+from io import StringIO
+
+from six import PY2, PY3, text_type, binary_type, string_types, integer_types
 
 from logilab.mtconverter import xml_escape, html_unescape
 from logilab.common.date import ustrftime
 from logilab.common.deprecation import deprecated
 
+from cubicweb import _
 from cubicweb.utils import js_dumps
 
 
@@ -62,7 +65,7 @@
     return value
 
 def print_int(value, req, props, displaytime=True):
-    return unicode(value)
+    return text_type(value)
 
 def print_date(value, req, props, displaytime=True):
     return ustrftime(value, req.property_value('ui.date-format'))
@@ -92,7 +95,7 @@
 _('%d seconds')
 
 def print_timedelta(value, req, props, displaytime=True):
-    if isinstance(value, (int, long)):
+    if isinstance(value, integer_types):
         # `date - date`, unlike `datetime - datetime` gives an int
         # (number of days), not a timedelta
         # XXX should rql be fixed to return Int instead of Interval in
@@ -122,7 +125,7 @@
     return req._('no')
 
 def print_float(value, req, props, displaytime=True):
-    return unicode(req.property_value('ui.float-format') % value)
+    return text_type(req.property_value('ui.float-format') % value) # XXX cast needed ?
 
 PRINTERS = {
     'Bytes': print_bytes,
@@ -337,9 +340,8 @@
     def __unicode__(self):
         if self.parent:
             return u'%s.%s' % (self.parent, self.id)
-        return unicode(self.id)
-    def __str__(self):
-        return unicode(self).encode('utf8')
+        return text_type(self.id)
+    __str__ = __unicode__ if PY3 else lambda self: self.__unicode__().encode('utf-8')
     def __getattr__(self, attr):
         return _JSId(attr, self)
     def __call__(self, *args):
@@ -357,6 +359,7 @@
         if self.parent:
             return u'%s(%s)' % (self.parent, ','.join(args))
         return ','.join(args)
+    __str__ = __unicode__ if PY3 else lambda self: self.__unicode__().encode('utf-8')
 
 class _JS(object):
     def __getattr__(self, attr):
@@ -389,7 +392,7 @@
                               'img', 'area', 'input', 'col'))
 
 def sgml_attributes(attrs):
-    return u' '.join(u'%s="%s"' % (attr, xml_escape(unicode(value)))
+    return u' '.join(u'%s="%s"' % (attr, xml_escape(text_type(value)))
                      for attr, value in sorted(attrs.items())
                      if value is not None)
 
@@ -407,7 +410,7 @@
         value += u' ' + sgml_attributes(attrs)
     if content:
         if escapecontent:
-            content = xml_escape(unicode(content))
+            content = xml_escape(text_type(content))
         value += u'>%s</%s>' % (content, tag)
     else:
         if tag in HTML4_EMPTY_TAGS:
@@ -436,8 +439,8 @@
     stream = StringIO() #UStringIO() don't want unicode assertion
     formater.format(layout, stream)
     res = stream.getvalue()
-    if isinstance(res, str):
-        res = unicode(res, 'UTF8')
+    if isinstance(res, binary_type):
+        res = res.decode('UTF8')
     return res
 
 # traceback formatting ########################################################
@@ -445,14 +448,17 @@
 import traceback
 
 def exc_message(ex, encoding):
-    try:
-        excmsg = unicode(ex)
-    except Exception:
+    if PY3:
+        excmsg = str(ex)
+    else:
         try:
-            excmsg = unicode(str(ex), encoding, 'replace')
+            excmsg = unicode(ex)
         except Exception:
-            excmsg = unicode(repr(ex), encoding, 'replace')
-    exctype = unicode(ex.__class__.__name__)
+            try:
+                excmsg = unicode(str(ex), encoding, 'replace')
+            except Exception:
+                excmsg = unicode(repr(ex), encoding, 'replace')
+    exctype = ex.__class__.__name__
     return u'%s: %s' % (exctype, excmsg)
 
 
@@ -462,7 +468,10 @@
     for stackentry in traceback.extract_tb(info[2]):
         res.append(u'\tFile %s, line %s, function %s' % tuple(stackentry[:3]))
         if stackentry[3]:
-            res.append(u'\t  %s' % stackentry[3].decode('utf-8', 'replace'))
+            data = xml_escape(stackentry[3])
+            if PY2:
+                data = data.decode('utf-8', 'replace')
+            res.append(u'\t  %s' % data)
     res.append(u'\n')
     try:
         res.append(u'\t Error: %s\n' % exception)
@@ -496,14 +505,16 @@
                        u'<b class="function">%s</b>:<br/>'%(
             xml_escape(stackentry[0]), stackentry[1], xml_escape(stackentry[2])))
         if stackentry[3]:
-            string = xml_escape(stackentry[3]).decode('utf-8', 'replace')
+            string = xml_escape(stackentry[3])
+            if PY2:
+                string = string.decode('utf-8', 'replace')
             strings.append(u'&#160;&#160;%s<br/>\n' % (string))
         # add locals info for each entry
         try:
             local_context = tcbk.tb_frame.f_locals
             html_info = []
             chars = 0
-            for name, value in local_context.iteritems():
+            for name, value in local_context.items():
                 value = xml_escape(repr(value))
                 info = u'<span class="name">%s</span>=%s, ' % (name, value)
                 line_length = len(name) + len(value)
@@ -526,7 +537,9 @@
 # csv files / unicode support #################################################
 
 class UnicodeCSVWriter:
-    """proxies calls to csv.writer.writerow to be able to deal with unicode"""
+    """proxies calls to csv.writer.writerow to be able to deal with unicode
+
+    Under Python 3, this code no longer encodes anything."""
 
     def __init__(self, wfunc, encoding, **kwargs):
         self.writer = csv.writer(self, **kwargs)
@@ -537,9 +550,12 @@
         self.wfunc(data)
 
     def writerow(self, row):
+        if PY3:
+            self.writer.writerow(row)
+            return
         csvrow = []
         for elt in row:
-            if isinstance(elt, unicode):
+            if isinstance(elt, text_type):
                 csvrow.append(elt.encode(self.encoding))
             else:
                 csvrow.append(str(elt))
@@ -559,7 +575,7 @@
     def __call__(self, function):
         def newfunc(*args, **kwargs):
             ret = function(*args, **kwargs)
-            if isinstance(ret, basestring):
+            if isinstance(ret, string_types):
                 return ret[:self.maxsize]
             return ret
         return newfunc
@@ -568,6 +584,6 @@
 def htmlescape(function):
     def newfunc(*args, **kwargs):
         ret = function(*args, **kwargs)
-        assert isinstance(ret, basestring)
+        assert isinstance(ret, string_types)
         return xml_escape(ret)
     return newfunc
--- a/utils.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/utils.py	Thu Dec 10 12:34:15 2015 +0100
@@ -33,9 +33,10 @@
 from uuid import uuid4
 from warnings import warn
 from threading import Lock
-from urlparse import urlparse
+from logging import getLogger
 
-from logging import getLogger
+from six import text_type
+from six.moves.urllib.parse import urlparse
 
 from logilab.mtconverter import xml_escape
 from logilab.common.deprecation import deprecated
@@ -100,7 +101,7 @@
     """
     def __init__(self, w, tag, closetag=None):
         self.written = False
-        self.tag = unicode(tag)
+        self.tag = text_type(tag)
         self.closetag = closetag
         self.w = w
 
@@ -116,7 +117,7 @@
     def __exit__(self, exctype, value, traceback):
         if self.written is True:
             if self.closetag:
-                self.w(unicode(self.closetag))
+                self.w(text_type(self.closetag))
             else:
                 self.w(self.tag.replace('<', '</', 1))
 
@@ -138,39 +139,6 @@
             yield subchild
 
 
-class SizeConstrainedList(list):
-    """simple list that makes sure the list does not get bigger than a given
-    size.
-
-    when the list is full and a new element is added, the first element of the
-    list is removed before appending the new one
-
-    >>> l = SizeConstrainedList(2)
-    >>> l.append(1)
-    >>> l.append(2)
-    >>> l
-    [1, 2]
-    >>> l.append(3)
-    >>> l
-    [2, 3]
-    """
-    def __init__(self, maxsize):
-        self.maxsize = maxsize
-
-    def append(self, element):
-        if len(self) == self.maxsize:
-            del self[0]
-        super(SizeConstrainedList, self).append(element)
-
-    def extend(self, sequence):
-        super(SizeConstrainedList, self).extend(sequence)
-        keepafter = len(self) - self.maxsize
-        if keepafter > 0:
-            del self[:keepafter]
-
-    __iadd__ = extend
-
-
 class RepeatList(object):
     """fake a list with the same element in each row"""
     __slots__ = ('_size', '_item')
@@ -185,13 +153,13 @@
     def __iter__(self):
         return repeat(self._item, self._size)
     def __getitem__(self, index):
+        if isinstance(index, slice):
+            # XXX could be more efficient, but do we bother?
+            return ([self._item] * self._size)[index]
         return self._item
     def __delitem__(self, idc):
         assert self._size > 0
         self._size -= 1
-    def __getslice__(self, i, j):
-        # XXX could be more efficient, but do we bother?
-        return ([self._item] * self._size)[i:j]
     def __add__(self, other):
         if isinstance(other, RepeatList):
             if other._item == self._item:
@@ -208,8 +176,10 @@
         if isinstance(other, RepeatList):
             return other._size == self._size and other._item == self._item
         return self[:] == other
-    # py3k future warning "Overriding __eq__ blocks inheritance of __hash__ in 3.x"
-    # is annoying but won't go away because we don't want to hash() the repeatlist
+    def __ne__(self, other):
+        return not (self == other)
+    def __hash__(self):
+        raise NotImplementedError
     def pop(self, i):
         self._size -= 1
 
@@ -223,11 +193,13 @@
         self.tracewrites = tracewrites
         super(UStringIO, self).__init__(*args, **kwargs)
 
-    def __nonzero__(self):
+    def __bool__(self):
         return True
 
+    __nonzero__ = __bool__
+
     def write(self, value):
-        assert isinstance(value, unicode), u"unicode required not %s : %s"\
+        assert isinstance(value, text_type), u"unicode required not %s : %s"\
                                      % (type(value).__name__, repr(value))
         if self.tracewrites:
             from traceback import format_stack
@@ -553,9 +525,9 @@
 
 def _dict2js(d, predictable=False):
     if predictable:
-        it = sorted(d.iteritems())
+        it = sorted(d.items())
     else:
-        it = d.iteritems()
+        it = d.items()
     res = [key + ': ' + js_dumps(val, predictable)
            for key, val in it]
     return '{%s}' % ', '.join(res)
--- a/view.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/view.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,12 +18,14 @@
 """abstract views and templates classes for CubicWeb web client"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from io import BytesIO
 from warnings import warn
 from functools import partial
 
+from six.moves import range
+
 from logilab.common.deprecation import deprecated
 from logilab.common.registry import yes
 from logilab.mtconverter import xml_escape
@@ -173,7 +175,7 @@
         # specific view
         if rset.rowcount != 1:
             kwargs.setdefault('initargs', self.cw_extra_kwargs)
-            for i in xrange(len(rset)):
+            for i in range(len(rset)):
                 if wrap:
                     self.w(u'<div class="section">')
                 self.wview(self.__regid__, rset, row=i, **kwargs)
@@ -213,7 +215,7 @@
             return self._cw.build_url('view', vid=self.__regid__)
         coltypes = rset.column_types(0)
         if len(coltypes) == 1:
-            etype = iter(coltypes).next()
+            etype = next(iter(coltypes))
             if not self._cw.vreg.schema.eschema(etype).final:
                 if len(rset) == 1:
                     entity = rset.get_entity(0, 0)
@@ -281,7 +283,7 @@
             else :
                 etypes = rset.column_types(0)
                 if len(etypes) == 1:
-                    etype = iter(etypes).next()
+                    etype = next(iter(etypes))
                     clabel = display_name(self._cw, etype, 'plural')
                 else :
                     clabel = u'#[*] (%s)' % vtitle
@@ -394,7 +396,7 @@
         if rset is None:
             rset = self.cw_rset = self._cw.execute(self.startup_rql())
         if rset:
-            for i in xrange(len(rset)):
+            for i in range(len(rset)):
                 self.wview(self.__regid__, rset, row=i, **kwargs)
         else:
             self.no_entities(**kwargs)
--- a/web/__init__.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/__init__.py	Thu Dec 10 12:34:15 2015 +0100
@@ -20,10 +20,9 @@
 """
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
-from urllib import quote as urlquote
-
+from six.moves.urllib.parse import quote as urlquote
 from logilab.common.deprecation import deprecated
 
 from cubicweb.web._exceptions import *
--- a/web/_exceptions.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/_exceptions.py	Thu Dec 10 12:34:15 2015 +0100
@@ -20,7 +20,7 @@
 
 __docformat__ = "restructuredtext en"
 
-import httplib
+from six.moves import http_client
 
 from cubicweb._exceptions import *
 from cubicweb.utils import json_dumps
@@ -41,7 +41,7 @@
     """base class for publishing related exception"""
 
     def __init__(self, *args, **kwargs):
-        self.status = kwargs.pop('status', httplib.OK)
+        self.status = kwargs.pop('status', http_client.OK)
         super(PublishException, self).__init__(*args, **kwargs)
 
 class LogOut(PublishException):
@@ -52,7 +52,7 @@
 
 class Redirect(PublishException):
     """raised to redirect the http request"""
-    def __init__(self, location, status=httplib.SEE_OTHER):
+    def __init__(self, location, status=http_client.SEE_OTHER):
         super(Redirect, self).__init__(status=status)
         self.location = location
 
@@ -71,7 +71,7 @@
     """raised when a request can't be served because of a bad input"""
 
     def __init__(self, *args, **kwargs):
-        kwargs.setdefault('status', httplib.BAD_REQUEST)
+        kwargs.setdefault('status', http_client.BAD_REQUEST)
         super(RequestError, self).__init__(*args, **kwargs)
 
 
@@ -79,14 +79,14 @@
     """raised when an edit request doesn't specify any eid to edit"""
 
     def __init__(self, *args, **kwargs):
-        kwargs.setdefault('status', httplib.BAD_REQUEST)
+        kwargs.setdefault('status', http_client.BAD_REQUEST)
         super(NothingToEdit, self).__init__(*args, **kwargs)
 
 class ProcessFormError(RequestError):
     """raised when posted data can't be processed by the corresponding field
     """
     def __init__(self, *args, **kwargs):
-        kwargs.setdefault('status', httplib.BAD_REQUEST)
+        kwargs.setdefault('status', http_client.BAD_REQUEST)
         super(ProcessFormError, self).__init__(*args, **kwargs)
 
 class NotFound(RequestError):
@@ -94,13 +94,13 @@
        a 404 error should be returned"""
 
     def __init__(self, *args, **kwargs):
-        kwargs.setdefault('status', httplib.NOT_FOUND)
+        kwargs.setdefault('status', http_client.NOT_FOUND)
         super(NotFound, self).__init__(*args, **kwargs)
 
 class RemoteCallFailed(RequestError):
     """raised when a json remote call fails
     """
-    def __init__(self, reason='', status=httplib.INTERNAL_SERVER_ERROR):
+    def __init__(self, reason='', status=http_client.INTERNAL_SERVER_ERROR):
         super(RemoteCallFailed, self).__init__(reason, status=status)
         self.reason = reason
 
--- a/web/action.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/action.py	Thu Dec 10 12:34:15 2015 +0100
@@ -33,7 +33,7 @@
 """
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from cubicweb import target
 from cubicweb.predicates import (partial_relation_possible, match_search_state,
@@ -91,7 +91,7 @@
     """base class for actions consisting to create a new object with an initial
     relation set to an entity.
 
-    Additionaly to EntityAction behaviour, this class is parametrized using
+    Additionally to EntityAction behaviour, this class is parametrized using
     .rtype, .role and .target_etype attributes to check if the action apply and
     if the logged user has access to it (see
     :class:`~cubicweb.selectors.partial_relation_possible` selector
@@ -111,4 +111,3 @@
         return self._cw.vreg["etypes"].etype_class(ttype).cw_create_url(self._cw,
                                   __redirectpath=entity.rest_path(), __linkto=linkto,
                                   __redirectvid=self._cw.form.get('__redirectvid', ''))
-
--- a/web/application.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/application.py	Thu Dec 10 12:34:15 2015 +0100
@@ -25,7 +25,8 @@
 from warnings import warn
 import json
 
-import httplib
+from six import text_type, binary_type
+from six.moves import http_client
 
 from logilab.common.deprecation import deprecated
 
@@ -68,8 +69,8 @@
     def __init__(self, appli):
         self.repo = appli.repo
         self.vreg = appli.vreg
-        self.session_manager = self.vreg['components'].select('sessionmanager',
-                                                              repo=self.repo)
+        self.session_manager = self.vreg['sessions'].select('sessionmanager',
+                                                            repo=self.repo)
         global SESSION_MANAGER
         SESSION_MANAGER = self.session_manager
         if self.vreg.config.mode != 'test':
@@ -80,8 +81,8 @@
 
     def reset_session_manager(self):
         data = self.session_manager.dump_data()
-        self.session_manager = self.vreg['components'].select('sessionmanager',
-                                                              repo=self.repo)
+        self.session_manager = self.vreg['sessions'].select('sessionmanager',
+                                                            repo=self.repo)
         self.session_manager.restore_data(data)
         global SESSION_MANAGER
         SESSION_MANAGER = self.session_manager
@@ -256,7 +257,7 @@
             # activate realm-based auth
             realm = self.vreg.config['realm']
             req.set_header('WWW-Authenticate', [('Basic', {'realm' : realm })], raw=False)
-        content = ''
+        content = b''
         try:
             try:
                 session = self.get_session(req)
@@ -290,7 +291,7 @@
                 if self.vreg.config['auth-mode'] == 'cookie' and ex.url:
                     req.headers_out.setHeader('location', str(ex.url))
                 if ex.status is not None:
-                    req.status_out = httplib.SEE_OTHER
+                    req.status_out = http_client.SEE_OTHER
                 # When the authentification is handled by http we must
                 # explicitly ask for authentification to flush current http
                 # authentification information
@@ -310,23 +311,24 @@
             # the request does not use https, redirect to login form
             https_url = self.vreg.config['https-url']
             if https_url and req.base_url() != https_url:
-                req.status_out = httplib.SEE_OTHER
+                req.status_out = http_client.SEE_OTHER
                 req.headers_out.setHeader('location', https_url + 'login')
             else:
                 # We assume here that in http auth mode the user *May* provide
                 # Authentification Credential if asked kindly.
                 if self.vreg.config['auth-mode'] == 'http':
-                    req.status_out = httplib.UNAUTHORIZED
+                    req.status_out = http_client.UNAUTHORIZED
                 # In the other case (coky auth) we assume that there is no way
                 # for the user to provide them...
                 # XXX But WHY ?
                 else:
-                    req.status_out = httplib.FORBIDDEN
+                    req.status_out = http_client.FORBIDDEN
                 # If previous error handling already generated a custom content
                 # do not overwrite it. This is used by LogOut Except
                 # XXX ensure we don't actually serve content
                 if not content:
                     content = self.need_login_content(req)
+        assert isinstance(content, binary_type)
         return content
 
 
@@ -368,7 +370,7 @@
             except cors.CORSPreflight:
                 # Return directly an empty 200
                 req.status_out = 200
-                result = ''
+                result = b''
             except StatusResponse as ex:
                 warn('[3.16] StatusResponse is deprecated use req.status_out',
                      DeprecationWarning, stacklevel=2)
@@ -394,12 +396,12 @@
         except Unauthorized as ex:
             req.data['errmsg'] = req._('You\'re not authorized to access this page. '
                                        'If you think you should, please contact the site administrator.')
-            req.status_out = httplib.FORBIDDEN
+            req.status_out = http_client.FORBIDDEN
             result = self.error_handler(req, ex, tb=False)
         except Forbidden as ex:
             req.data['errmsg'] = req._('This action is forbidden. '
                                        'If you think it should be allowed, please contact the site administrator.')
-            req.status_out = httplib.FORBIDDEN
+            req.status_out = http_client.FORBIDDEN
             result = self.error_handler(req, ex, tb=False)
         except (BadRQLQuery, RequestError) as ex:
             result = self.error_handler(req, ex, tb=False)
@@ -413,7 +415,7 @@
             raise
         ### Last defense line
         except BaseException as ex:
-            req.status_out = httplib.INTERNAL_SERVER_ERROR
+            req.status_out = http_client.INTERNAL_SERVER_ERROR
             result = self.error_handler(req, ex, tb=True)
         finally:
             if req.cnx and not commited:
@@ -437,7 +439,7 @@
         req.headers_out.setHeader('location', str(ex.location))
         assert 300 <= ex.status < 400
         req.status_out = ex.status
-        return ''
+        return b''
 
     def validation_error_handler(self, req, ex):
         ex.translate(req._) # translate messages using ui language
@@ -453,9 +455,9 @@
             # messages.
             location = req.form['__errorurl'].rsplit('#', 1)[0]
             req.headers_out.setHeader('location', str(location))
-            req.status_out = httplib.SEE_OTHER
-            return ''
-        req.status_out = httplib.CONFLICT
+            req.status_out = http_client.SEE_OTHER
+            return b''
+        req.status_out = http_client.CONFLICT
         return self.error_handler(req, ex, tb=False)
 
     def error_handler(self, req, ex, tb=False):
@@ -491,14 +493,14 @@
 
     def ajax_error_handler(self, req, ex):
         req.set_header('content-type', 'application/json')
-        status = httplib.INTERNAL_SERVER_ERROR
+        status = http_client.INTERNAL_SERVER_ERROR
         if isinstance(ex, PublishException) and ex.status is not None:
             status = ex.status
         if req.status_out < 400:
             # don't overwrite it if it's already set
             req.status_out = status
-        json_dumper = getattr(ex, 'dumps', lambda : json.dumps({'reason': unicode(ex)}))
-        return json_dumper()
+        json_dumper = getattr(ex, 'dumps', lambda : json.dumps({'reason': text_type(ex)}))
+        return json_dumper().encode('utf-8')
 
     # special case handling
 
--- a/web/box.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/box.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,7 +18,9 @@
 """abstract box classes for CubicWeb web client"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
+
+from six import add_metaclass
 
 from logilab.mtconverter import xml_escape
 from logilab.common.deprecation import class_deprecated, class_renamed
@@ -41,7 +43,7 @@
         actions_by_cat.setdefault(action.category, []).append(
             (action.title, action) )
     for key, values in actions_by_cat.items():
-        actions_by_cat[key] = [act for title, act in sorted(values)]
+        actions_by_cat[key] = [act for title, act in sorted(values, key=lambda x: x[0])]
     if categories_in_order:
         for cat in categories_in_order:
             if cat in actions_by_cat:
@@ -53,6 +55,7 @@
 
 # old box system, deprecated ###################################################
 
+@add_metaclass(class_deprecated)
 class BoxTemplate(View):
     """base template for boxes, usually a (contextual) list of possible
     actions. Various classes attributes may be used to control the box
@@ -66,7 +69,6 @@
 
         box.render(self.w)
     """
-    __metaclass__ = class_deprecated
     __deprecation_warning__ = '[3.10] *BoxTemplate classes are deprecated, use *CtxComponent instead (%(cls)s)'
 
     __registry__ = 'ctxcomponents'
@@ -193,4 +195,3 @@
 AjaxEditRelationBoxTemplate = class_renamed(
     'AjaxEditRelationBoxTemplate', AjaxEditRelationCtxComponent,
     '[3.10] AjaxEditRelationBoxTemplate has been renamed to AjaxEditRelationCtxComponent (%(cls)s)')
-
--- a/web/captcha.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/captcha.py	Thu Dec 10 12:34:15 2015 +0100
@@ -22,7 +22,9 @@
 __docformat__ = "restructuredtext en"
 
 from random import randint, choice
-from cStringIO import StringIO
+from io import BytesIO
+
+from six.moves import range
 
 from PIL import Image, ImageFont, ImageDraw, ImageFilter
 
@@ -51,7 +53,7 @@
     draw = ImageDraw.Draw(img)
     # draw 100 random colored boxes on the background
     x, y = img.size
-    for num in xrange(100):
+    for num in range(100):
         draw.rectangle((randint(0, x), randint(0, y),
                         randint(0, x), randint(0, y)),
                        fill=randint(0, 0xffffff))
@@ -67,7 +69,7 @@
     """
     text = u''.join(choice('QWERTYUOPASDFGHJKLZXCVBNM') for i in range(size))
     img = pil_captcha(text, fontfile, fontsize)
-    out = StringIO()
+    out = BytesIO()
     img.save(out, format)
     out.seek(0)
     return text, out
--- a/web/component.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/component.py	Thu Dec 10 12:34:15 2015 +0100
@@ -20,10 +20,12 @@
 """
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from warnings import warn
 
+from six import PY3, add_metaclass, text_type
+
 from logilab.common.deprecation import class_deprecated, class_renamed, deprecated
 from logilab.mtconverter import xml_escape
 
@@ -215,6 +217,9 @@
     def __unicode__(self):
         return tags.a(self.label, href=self.href, **self.attrs)
 
+    if PY3:
+        __str__ = __unicode__
+
     def render(self, w):
         w(tags.a(self.label, href=self.href, **self.attrs))
 
@@ -425,7 +430,7 @@
 
     @property
     def domid(self):
-        return domid(self.__regid__) + unicode(self.entity.eid)
+        return domid(self.__regid__) + text_type(self.entity.eid)
 
     def lazy_view_holder(self, w, entity, oid, registry='views'):
         """add a holder and return a URL that may be used to replace this
@@ -498,7 +503,7 @@
                                                     args['subject'],
                                                     args['object'])
         return u'[<a href="javascript: %s" class="action">%s</a>] %s' % (
-            xml_escape(unicode(jscall)), label, etarget.view('incontext'))
+            xml_escape(text_type(jscall)), label, etarget.view('incontext'))
 
     def related_boxitems(self, entity):
         return [self.box_item(entity, etarget, 'delete_relation', u'-')
@@ -515,7 +520,7 @@
         """returns the list of unrelated entities, using the entity's
         appropriate vocabulary function
         """
-        skip = set(unicode(e.eid) for e in entity.related(self.rtype, role(self),
+        skip = set(text_type(e.eid) for e in entity.related(self.rtype, role(self),
                                                           entities=True))
         skip.add(None)
         skip.add(INTERNAL_FIELD_VALUE)
@@ -571,7 +576,7 @@
 
     # to be defined in concrete classes
     rtype = role = target_etype = None
-    # class attributes below *must* be set in concrete classes (additionaly to
+    # class attributes below *must* be set in concrete classes (additionally to
     # rtype / role [/ target_etype]. They should correspond to js_* methods on
     # the json controller
 
@@ -633,7 +638,7 @@
                 if maydel:
                     if not js_css_added:
                         js_css_added = self.add_js_css()
-                    jscall = unicode(js.ajaxBoxRemoveLinkedEntity(
+                    jscall = text_type(js.ajaxBoxRemoveLinkedEntity(
                         self.__regid__, entity.eid, rentity.eid,
                         self.fname_remove,
                         self.removed_msg and _(self.removed_msg)))
@@ -648,7 +653,7 @@
         if mayadd:
             multiple = self.rdef.role_cardinality(self.role) in '*+'
             w(u'<table><tr><td>')
-            jscall = unicode(js.ajaxBoxShowSelector(
+            jscall = text_type(js.ajaxBoxShowSelector(
                 self.__regid__, entity.eid, self.fname_vocabulary,
                 self.fname_validate, self.added_msg and _(self.added_msg),
                 _(stdmsgs.BUTTON_OK[0]), _(stdmsgs.BUTTON_CANCEL[0]),
@@ -677,6 +682,7 @@
 
 # old contextual components, deprecated ########################################
 
+@add_metaclass(class_deprecated)
 class EntityVComponent(Component):
     """abstract base class for additinal components displayed in content
     headers and footer according to:
@@ -687,7 +693,6 @@
     it should be configured using .accepts, .etype, .rtype, .target and
     .context class attributes
     """
-    __metaclass__ = class_deprecated
     __deprecation_warning__ = '[3.10] *VComponent classes are deprecated, use *CtxComponent instead (%(cls)s)'
 
     __registry__ = 'ctxcomponents'
--- a/web/controller.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/controller.py	Thu Dec 10 12:34:15 2015 +0100
@@ -19,6 +19,8 @@
 
 __docformat__ = "restructuredtext en"
 
+from six import PY2
+
 from logilab.mtconverter import xml_escape
 from logilab.common.registry import yes
 from logilab.common.deprecation import deprecated
@@ -87,7 +89,7 @@
         rql = req.form.get('rql')
         if rql:
             req.ensure_ro_rql(rql)
-            if not isinstance(rql, unicode):
+            if PY2 and not isinstance(rql, unicode):
                 rql = unicode(rql, req.encoding)
             pp = req.vreg['components'].select_or_none('magicsearch', req)
             if pp is not None:
@@ -132,8 +134,6 @@
             newparams['_cwmsgid'] = self._cw.set_redirect_message(msg)
         if '__action_apply' in self._cw.form:
             self._return_to_edition_view(newparams)
-        if '__action_cancel' in self._cw.form:
-            self._return_to_lastpage(newparams)
         else:
             self._return_to_original_view(newparams)
 
@@ -155,7 +155,7 @@
                 and '_cwmsgid' in newparams):
                 # are we here on creation or modification?
                 if any(eid == self._edited_entity.eid
-                       for eid in self._cw.data.get('eidmap', {}).itervalues()):
+                       for eid in self._cw.data.get('eidmap', {}).values()):
                     msg = self._cw._('click here to see created entity')
                 else:
                     msg = self._cw._('click here to see edited entity')
@@ -201,11 +201,9 @@
         raise Redirect(self._cw.build_url(path, **newparams))
 
 
-    def _return_to_lastpage(self, newparams):
-        """cancel-button case: in this case we are always expecting to go back
-        where we came from, and this is not easy. Currently we suppose that
-        __redirectpath is specifying that place if found, else we look in the
-        request breadcrumbs for the last visited page.
+    def _redirect(self, newparams):
+        """Raise a redirect. We use __redirectpath if it specified, else we
+        return to the home page.
         """
         if '__redirectpath' in self._cw.form:
             # if redirect path was explicitly specified in the form, use it
@@ -213,7 +211,7 @@
             url = self._cw.build_url(path)
             url = append_url_params(url, self._cw.form.get('__redirectparams'))
         else:
-            url = self._cw.last_visited_page()
+            url = self._cw.base_url()
         # The newparams must update the params in all cases
         url = self._cw.rebuild_url(url, **newparams)
         raise Redirect(url)
@@ -221,4 +219,3 @@
 
 from cubicweb import set_log_methods
 set_log_methods(Controller, LOGGER)
-
--- a/web/cors.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/cors.py	Thu Dec 10 12:34:15 2015 +0100
@@ -14,7 +14,7 @@
 
 """
 
-import urlparse
+from six.moves.urllib.parse import urlsplit
 
 from cubicweb.web import LOGGER
 info = LOGGER.info
@@ -37,7 +37,7 @@
 
     In case of non-compliance, no CORS-related header is set.
     """
-    base_url = urlparse.urlsplit(req.base_url())
+    base_url = urlsplit(req.base_url())
     expected_host = '://'.join((base_url.scheme, base_url.netloc))
     if not req.get_header('Origin') or req.get_header('Origin') == expected_host:
         # not a CORS request, nothing to do
@@ -50,7 +50,7 @@
                 process_preflight(req, config)
         else: # Simple CORS or actual request
             process_simple(req, config)
-    except CORSFailed, exc:
+    except CORSFailed as exc:
         info('Cross origin resource sharing failed: %s' % exc)
     except CORSPreflight:
         info('Cross origin resource sharing: valid Preflight request %s')
@@ -101,7 +101,7 @@
     if '*' not in allowed_origins and origin not in allowed_origins:
         raise CORSFailed('Origin is not allowed')
     # bit of sanity check; see "6.3 Security"
-    myhost = urlparse.urlsplit(req.base_url()).netloc
+    myhost = urlsplit(req.base_url()).netloc
     host = req.get_header('Host')
     if host != myhost:
         info('cross origin resource sharing detected possible '
@@ -111,4 +111,3 @@
     # include "Vary: Origin" header (see 6.4)
     req.headers_out.addHeader('Vary', 'Origin')
     return origin
-
--- a/web/data/cubicweb.edition.js	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/data/cubicweb.edition.js	Thu Dec 10 12:34:15 2015 +0100
@@ -537,6 +537,24 @@
 }
 
 /**
+ * Cancel the operations done on the given form.
+ *
+ */
+$(function () {
+    $(document).on('click', '.cwjs-edition-cancel', function (evt) {
+        var $mynode = $(evt.currentTarget),
+            $form = $mynode.closest('form'),
+            $error = $form.find(':input[name="__errorurl"]'),
+            errorurl = $error.attr('value'),
+            args = ajaxFuncArgs('cancel_edition', null, errorurl);
+        loadRemote(AJAX_BASE_URL, args, 'POST', true);
+        history.back();
+        return false;
+    });
+});
+
+
+/**
  * .. function:: validateForm(formid, action, onsuccess, onfailure)
  *
  * called on traditionnal form submission : the idea is to try
--- a/web/facet.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/facet.py	Thu Dec 10 12:34:15 2015 +0100
@@ -50,13 +50,15 @@
 """
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from functools import reduce
 from warnings import warn
 from copy import deepcopy
 from datetime import datetime, timedelta
 
+from six import text_type, string_types
+
 from logilab.mtconverter import xml_escape
 from logilab.common.graph import has_path
 from logilab.common.decorators import cached, cachedproperty
@@ -80,7 +82,7 @@
         ptypes = facet.cw_rset.column_types(0)
         if len(ptypes) == 1:
             return display_name(facet._cw, facet.rtype, form=facet.role,
-                                context=iter(ptypes).next())
+                                context=next(iter(ptypes)))
     return display_name(facet._cw, facet.rtype, form=facet.role)
 
 def get_facet(req, facetid, select, filtered_variable):
@@ -133,7 +135,7 @@
     or the first variable selected in column 0
     """
     if mainvar is None:
-        vref = select.selection[0].iget_nodes(nodes.VariableRef).next()
+        vref = next(select.selection[0].iget_nodes(nodes.VariableRef))
         return vref.variable
     return select.defined_vars[mainvar]
 
@@ -156,7 +158,7 @@
     for term in select.selection[:]:
         select.remove_selected(term)
     # remove unbound variables which only have some type restriction
-    for dvar in list(select.defined_vars.itervalues()):
+    for dvar in list(select.defined_vars.values()):
         if not (dvar is filtered_variable or dvar.stinfo['relations']):
             select.undefine_variable(dvar)
     # global tree config: DISTINCT, LIMIT, OFFSET
@@ -305,7 +307,7 @@
         # optional relation
         return ovar
     if all(rdef.cardinality[cardidx] in '1+'
-           for rdef in rschema.rdefs.itervalues()):
+           for rdef in rschema.rdefs.values()):
         # mandatory relation without any restriction on the other variable
         for orel in ovar.stinfo['relations']:
             if rel is orel:
@@ -670,7 +672,7 @@
                 insert_attr_select_relation(
                     select, self.filtered_variable, self.rtype, self.role,
                     self.target_attr, select_target_entity=False)
-            values = [unicode(x) for x, in self.rqlexec(select.as_string())]
+            values = [text_type(x) for x, in self.rqlexec(select.as_string())]
         except Exception:
             self.exception('while computing values for %s', self)
             return []
@@ -719,14 +721,14 @@
 
     def rset_vocabulary(self, rset):
         if self.i18nable:
-            _ = self._cw._
+            tr = self._cw._
         else:
-            _ = unicode
+            tr = text_type
         if self.rql_sort:
-            values = [(_(label), eid) for eid, label in rset]
+            values = [(tr(label), eid) for eid, label in rset]
         else:
             if self.label_vid is None:
-                values = [(_(label), eid) for eid, label in rset]
+                values = [(tr(label), eid) for eid, label in rset]
             else:
                 values = [(entity.view(self.label_vid), entity.eid)
                           for entity in rset.entities()]
@@ -754,7 +756,7 @@
         # XXX handle rel is None case in RQLPathFacet?
         if self.restr_attr != 'eid':
             self.select.set_distinct(True)
-        if isinstance(value, basestring):
+        if isinstance(value, string_types):
             # only one value selected
             if value:
                 self.select.add_constant_restriction(
@@ -808,7 +810,7 @@
         rschema = self._cw.vreg.schema.rschema(self.rtype)
         # XXX when called via ajax, no rset to compute possible types
         possibletypes = self.cw_rset and self.cw_rset.column_types(0)
-        for rdef in rschema.rdefs.itervalues():
+        for rdef in rschema.rdefs.values():
             if possibletypes is not None:
                 if self.role == 'subject':
                     if rdef.subject not in possibletypes:
@@ -829,13 +831,13 @@
         if self._cw.vreg.schema.rschema(self.rtype).final:
             return False
         if self.role == 'object':
-            subj = utils.rqlvar_maker(defined=self.select.defined_vars,
-                                      aliases=self.select.aliases).next()
+            subj = next(utils.rqlvar_maker(defined=self.select.defined_vars,
+                                      aliases=self.select.aliases))
             obj = self.filtered_variable.name
         else:
             subj = self.filtered_variable.name
-            obj = utils.rqlvar_maker(defined=self.select.defined_vars,
-                                     aliases=self.select.aliases).next()
+            obj = next(utils.rqlvar_maker(defined=self.select.defined_vars,
+                                     aliases=self.select.aliases))
         restrictions = []
         if self.select.where:
             restrictions.append(self.select.where.as_string())
@@ -916,15 +918,13 @@
 
     def rset_vocabulary(self, rset):
         if self.i18nable:
-            _ = self._cw._
+            tr = self._cw._
         else:
-            _ = unicode
+            tr = text_type
         if self.rql_sort:
-            return [(_(value), value) for value, in rset]
-        values = [(_(value), value) for value, in rset]
-        if self.sortasc:
-            return sorted(values)
-        return reversed(sorted(values))
+            return [(tr(value), value) for value, in rset]
+        values = [(tr(value), value) for value, in rset]
+        return sorted(values, reverse=not self.sortasc)
 
 
 class AttributeFacet(RelationAttributeFacet):
@@ -1073,7 +1073,7 @@
         assert self.path and isinstance(self.path, (list, tuple)), \
             'path should be a list of 3-uples, not %s' % self.path
         for part in self.path:
-            if isinstance(part, basestring):
+            if isinstance(part, string_types):
                 part = part.split()
             assert len(part) == 3, \
                    'path should be a list of 3-uples, not %s' % part
@@ -1126,7 +1126,7 @@
             cleanup_select(select, self.filtered_variable)
             varmap, restrvar = self.add_path_to_select(skiplabel=True)
             select.append_selected(nodes.VariableRef(restrvar))
-            values = [unicode(x) for x, in self.rqlexec(select.as_string())]
+            values = [text_type(x) for x, in self.rqlexec(select.as_string())]
         except Exception:
             self.exception('while computing values for %s', self)
             return []
@@ -1149,7 +1149,7 @@
         varmap = {'X': self.filtered_variable}
         actual_filter_variable = None
         for part in self.path:
-            if isinstance(part, basestring):
+            if isinstance(part, string_types):
                 part = part.split()
             subject, rtype, object = part
             if skiplabel and object == self.label_variable:
@@ -1165,7 +1165,7 @@
                         if len(attrtypes) > 1:
                             raise Exception('ambigous attribute %s, specify attrtype on %s'
                                             % (rtype, self.__class__))
-                        self.restr_attr_type = iter(attrtypes).next()
+                        self.restr_attr_type = next(iter(attrtypes))
                     if skipattrfilter:
                         actual_filter_variable = subject
                         continue
@@ -1253,7 +1253,7 @@
         rset = self._range_rset()
         if rset:
             minv, maxv = rset[0]
-            return [(unicode(minv), minv), (unicode(maxv), maxv)]
+            return [(text_type(minv), minv), (text_type(maxv), maxv)]
         return []
 
     def possible_values(self):
@@ -1272,7 +1272,7 @@
 
     def formatvalue(self, value):
         """format `value` before in order to insert it in the RQL query"""
-        return unicode(value)
+        return text_type(value)
 
     def infvalue(self, min=False):
         if min:
@@ -1373,7 +1373,7 @@
         # *list* (see rqlexec implementation)
         if rset:
             minv, maxv = rset[0]
-            return [(unicode(minv), minv), (unicode(maxv), maxv)]
+            return [(text_type(minv), minv), (text_type(maxv), maxv)]
         return []
 
 
@@ -1392,7 +1392,7 @@
             skiplabel=True, skipattrfilter=True)
         restrel = None
         for part in self.path:
-            if isinstance(part, basestring):
+            if isinstance(part, string_types):
                 part = part.split()
             subject, rtype, object = part
             if object == self.filter_variable:
@@ -1516,7 +1516,7 @@
                        if not val or val & mask])
 
     def possible_values(self):
-        return [unicode(val) for label, val in self.vocabulary()]
+        return [text_type(val) for label, val in self.vocabulary()]
 
 
 ## html widets ################################################################
@@ -1595,7 +1595,7 @@
         if selected:
             cssclass += ' facetValueSelected'
         w(u'<div class="%s" cubicweb:value="%s">\n'
-          % (cssclass, xml_escape(unicode(value))))
+          % (cssclass, xml_escape(text_type(value))))
         # If it is overflowed one must add padding to compensate for the vertical
         # scrollbar; given current css values, 4 blanks work perfectly ...
         padding = u'&#160;' * self.scrollbar_padding_factor if overflow else u''
@@ -1754,7 +1754,7 @@
             imgsrc = self._cw.data_url(self.unselected_img)
             imgalt = self._cw._('not selected')
         w(u'<div class="%s" cubicweb:value="%s">\n'
-          % (cssclass, xml_escape(unicode(self.value))))
+          % (cssclass, xml_escape(text_type(self.value))))
         w(u'<div>')
         w(u'<img src="%s" alt="%s" cubicweb:unselimg="true" />&#160;' % (imgsrc, imgalt))
         w(u'<label class="facetTitle" cubicweb:facetName="%s">%s</label>'
--- a/web/form.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/form.py	Thu Dec 10 12:34:15 2015 +0100
@@ -20,6 +20,8 @@
 
 from warnings import warn
 
+from six import add_metaclass
+
 from logilab.common.decorators import iclassmethod
 from logilab.common.deprecation import deprecated
 
@@ -74,8 +76,8 @@
     found
     """
 
+@add_metaclass(metafieldsform)
 class Form(AppObject):
-    __metaclass__ = metafieldsform
     __registry__ = 'forms'
 
     parent_form = None
@@ -120,7 +122,7 @@
         extrakw = {}
         # search for navigation parameters and customization of existing
         # attributes; remaining stuff goes in extrakwargs
-        for key, val in kwargs.iteritems():
+        for key, val in kwargs.items():
             if key in controller.NAV_FORM_PARAMETERS:
                 hiddens.append( (key, val) )
             elif key == 'redirect_path':
@@ -280,4 +282,3 @@
 
     def remaining_errors(self):
         return sorted(self.form_valerror.errors.items())
-
--- a/web/formfields.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/formfields.py	Thu Dec 10 12:34:15 2015 +0100
@@ -66,6 +66,8 @@
 from warnings import warn
 from datetime import datetime, timedelta
 
+from six import PY2, text_type, string_types
+
 from logilab.mtconverter import xml_escape
 from logilab.common import nullobject
 from logilab.common.date import ustrftime
@@ -159,7 +161,7 @@
     :attr:`order`
        key used by automatic forms to sort fields
     :attr:`ignore_req_params`
-       when true, this field won't consider value potentialy specified using
+       when true, this field won't consider value potentially specified using
        request's form parameters (eg you won't be able to specify a value using for
        instance url like http://mywebsite.com/form?field=value)
 
@@ -231,11 +233,14 @@
     def __unicode__(self):
         return self.as_string(False)
 
-    def __str__(self):
-        return self.as_string(False).encode('UTF8')
+    if PY2:
+        def __str__(self):
+            return self.as_string(False).encode('UTF8')
+    else:
+        __str__ = __unicode__
 
     def __repr__(self):
-        return self.as_string(True).encode('UTF8')
+        return self.as_string(True)
 
     def init_widget(self, widget):
         if widget is not None:
@@ -279,7 +284,7 @@
             return u''
         if value is True:
             return u'1'
-        return unicode(value)
+        return text_type(value)
 
     def get_widget(self, form):
         """return the widget instance associated to this field"""
@@ -381,7 +386,7 @@
         assert self.choices is not None
         if callable(self.choices):
             # pylint: disable=E1102
-            if getattr(self.choices, 'im_self', None) is self:
+            if getattr(self.choices, '__self__', None) is self:
                 vocab = self.choices(form=form, **kwargs)
             else:
                 vocab = self.choices(form=form, field=self, **kwargs)
@@ -508,7 +513,7 @@
 
 class StringField(Field):
     """Use this field to edit unicode string (`String` yams type). This field
-    additionaly support a `max_length` attribute that specify a maximum size for
+    additionally support a `max_length` attribute that specify a maximum size for
     the string (`None` meaning no limit).
 
     Unless explicitly specified, the widget for this field will be:
@@ -780,7 +785,7 @@
 
     If the stream format is one of text/plain, text/html, text/rest,
     text/markdown
-    then a :class:`~cubicweb.web.formwidgets.TextArea` will be additionaly
+    then a :class:`~cubicweb.web.formwidgets.TextArea` will be additionally
     displayed, allowing to directly the file's content when desired, instead
     of choosing a file from user's file system.
     """
@@ -794,7 +799,7 @@
             if data:
                 encoding = self.encoding(form)
                 try:
-                    form.formvalues[(self, form)] = unicode(data.getvalue(), encoding)
+                    form.formvalues[(self, form)] = data.getvalue().decode(encoding)
                 except UnicodeError:
                     pass
                 else:
@@ -815,7 +820,7 @@
 
     def _process_form_value(self, form):
         value = form._cw.form.get(self.input_name(form))
-        if isinstance(value, unicode):
+        if isinstance(value, text_type):
             # file modified using a text widget
             return Binary(value.encode(self.encoding(form)))
         return super(EditableFileField, self)._process_form_value(form)
@@ -823,7 +828,7 @@
 
 class BigIntField(Field):
     """Use this field to edit big integers (`BigInt` yams type). This field
-    additionaly support `min` and `max` attributes that specify a minimum and/or
+    additionally support `min` and `max` attributes that specify a minimum and/or
     maximum value for the integer (`None` meaning no boundary).
 
     Unless explicitly specified, the widget for this field will be a
@@ -842,7 +847,7 @@
             self.widget.attrs.setdefault('size', self.default_text_input_size)
 
     def _ensure_correctly_typed(self, form, value):
-        if isinstance(value, basestring):
+        if isinstance(value, string_types):
             value = value.strip()
             if not value:
                 return None
@@ -907,7 +912,7 @@
 
 
 class FloatField(IntField):
-    """Use this field to edit floats (`Float` yams type). This field additionaly
+    """Use this field to edit floats (`Float` yams type). This field additionally
     support `min` and `max` attributes as the
     :class:`~cubicweb.web.formfields.IntField`.
 
@@ -924,7 +929,7 @@
         return self.format_single_value(req, 1.234)
 
     def _ensure_correctly_typed(self, form, value):
-        if isinstance(value, basestring):
+        if isinstance(value, string_types):
             value = value.strip()
             if not value:
                 return None
@@ -946,7 +951,7 @@
     def format_single_value(self, req, value):
         if value:
             value = format_time(value.days * 24 * 3600 + value.seconds)
-            return unicode(value)
+            return text_type(value)
         return u''
 
     def example_format(self, req):
@@ -956,7 +961,7 @@
         return u'20s, 10min, 24h, 4d'
 
     def _ensure_correctly_typed(self, form, value):
-        if isinstance(value, basestring):
+        if isinstance(value, string_types):
             value = value.strip()
             if not value:
                 return None
@@ -986,14 +991,14 @@
         return self.format_single_value(req, datetime.now())
 
     def _ensure_correctly_typed(self, form, value):
-        if isinstance(value, basestring):
+        if isinstance(value, string_types):
             value = value.strip()
             if not value:
                 return None
             try:
                 value = form._cw.parse_datetime(value, self.etype)
             except ValueError as ex:
-                raise ProcessFormError(unicode(ex))
+                raise ProcessFormError(text_type(ex))
         return value
 
 
@@ -1083,7 +1088,7 @@
         linkedto = form.linked_to.get((self.name, self.role))
         if linkedto:
             buildent = form._cw.entity_from_eid
-            return [(buildent(eid).view('combobox'), unicode(eid))
+            return [(buildent(eid).view('combobox'), text_type(eid))
                     for eid in linkedto]
         return []
 
@@ -1095,7 +1100,7 @@
         # vocabulary doesn't include current values, add them
         if form.edited_entity.has_eid():
             rset = form.edited_entity.related(self.name, self.role)
-            vocab += [(e.view('combobox'), unicode(e.eid))
+            vocab += [(e.view('combobox'), text_type(e.eid))
                       for e in rset.entities()]
         return vocab
 
@@ -1129,11 +1134,11 @@
             if entity.eid in done:
                 continue
             done.add(entity.eid)
-            res.append((entity.view('combobox'), unicode(entity.eid)))
+            res.append((entity.view('combobox'), text_type(entity.eid)))
         return res
 
     def format_single_value(self, req, value):
-        return unicode(value)
+        return text_type(value)
 
     def process_form_value(self, form):
         """process posted form and return correctly typed value"""
--- a/web/formwidgets.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/formwidgets.py	Thu Dec 10 12:34:15 2015 +0100
@@ -99,6 +99,8 @@
 from datetime import date
 from warnings import warn
 
+from six import text_type, string_types
+
 from logilab.mtconverter import xml_escape
 from logilab.common.deprecation import deprecated
 from logilab.common.date import todatetime
@@ -282,7 +284,7 @@
         """
         posted = form._cw.form
         val = posted.get(field.input_name(form, self.suffix))
-        if isinstance(val, basestring):
+        if isinstance(val, string_types):
             val = val.strip()
         return val
 
@@ -416,7 +418,7 @@
         lines = value.splitlines()
         linecount = len(lines)
         for line in lines:
-            linecount += len(line) / self._columns
+            linecount += len(line) // self._columns
         attrs.setdefault('cols', self._columns)
         attrs.setdefault('rows', min(self._maxrows, linecount + self._minrows))
         return tags.textarea(value, name=field.input_name(form, self.suffix),
@@ -474,7 +476,7 @@
             options.append(u'</optgroup>')
         if not 'size' in attrs:
             if self._multiple:
-                size = unicode(min(self.default_size, len(vocab) or 1))
+                size = text_type(min(self.default_size, len(vocab) or 1))
             else:
                 size = u'1'
             attrs['size'] = size
@@ -616,7 +618,7 @@
                 iattrs['checked'] = u'checked'
             tag = tags.input(name=field.input_name(form, self.suffix),
                              type=self.type, value=value, **iattrs)
-            options.append(u'%s&#160;%s' % (tag, label))
+            options.append(u'<label>%s&#160;%s</label>' % (tag, xml_escape(label)))
         return sep.join(options)
 
 
@@ -706,7 +708,7 @@
         else:
             value = self.value
         attrs = self.attributes(form, field)
-        attrs.setdefault('size', unicode(self.default_size))
+        attrs.setdefault('size', text_type(self.default_size))
         return tags.input(name=field.input_name(form, self.suffix),
                           value=value, type='text', **attrs)
 
@@ -779,13 +781,13 @@
         try:
             date = todatetime(req.parse_datetime(datestr, 'Date'))
         except ValueError as exc:
-            raise ProcessFormError(unicode(exc))
+            raise ProcessFormError(text_type(exc))
         if timestr is None:
             return date
         try:
             time = req.parse_datetime(timestr, 'Time')
         except ValueError as exc:
-            raise ProcessFormError(unicode(exc))
+            raise ProcessFormError(text_type(exc))
         return date.replace(hour=time.hour, minute=time.minute, second=time.second)
 
 
@@ -993,12 +995,12 @@
         req = form._cw
         values = {}
         path = req.form.get(field.input_name(form, 'path'))
-        if isinstance(path, basestring):
+        if isinstance(path, string_types):
             path = path.strip()
         if path is None:
             path = u''
         fqs = req.form.get(field.input_name(form, 'fqs'))
-        if isinstance(fqs, basestring):
+        if isinstance(fqs, string_types):
             fqs = fqs.strip() or None
             if fqs:
                 for i, line in enumerate(fqs.split('\n')):
@@ -1009,7 +1011,7 @@
                         except ValueError:
                             raise ProcessFormError(req._("wrong query parameter line %s") % (i+1))
                         # value will be url quoted by build_url_params
-                        values.setdefault(key.encode(req.encoding), []).append(val)
+                        values.setdefault(key, []).append(val)
         if not values:
             return path
         return u'%s?%s' % (path, req.build_url_params(**values))
@@ -1094,4 +1096,3 @@
                '<img src="%(imgsrc)s" alt="%(label)s"/>%(label)s</a>' % {
             'label': label, 'imgsrc': imgsrc,
             'domid': self.domid, 'href': self.href}
-
--- a/web/htmlwidgets.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/htmlwidgets.py	Thu Dec 10 12:34:15 2015 +0100
@@ -24,6 +24,9 @@
 import random
 from math import floor
 
+from six import add_metaclass
+from six.moves import range
+
 from logilab.mtconverter import xml_escape
 from logilab.common.deprecation import class_deprecated
 
@@ -115,9 +118,9 @@
         self.w(u'</div>')
 
 
+@add_metaclass(class_deprecated)
 class SideBoxWidget(BoxWidget):
     """default CubicWeb's sidebox widget"""
-    __metaclass__ = class_deprecated
     __deprecation_warning__ = '[3.10] class %(cls)s is deprecated'
 
     title_class = u'sideBoxTitle'
@@ -207,9 +210,9 @@
         self.w(u'</ul></div></div>')
 
 
+@add_metaclass(class_deprecated)
 class BoxField(HTMLWidget):
     """couples label / value meant to be displayed in a box"""
-    __metaclass__ = class_deprecated
     __deprecation_warning__ = '[3.10] class %(cls)s is deprecated'
     def __init__(self, label, value):
         self.label = label
@@ -220,18 +223,19 @@
                u'<span class="value">%s</span></div></li>'
                % (self.label, self.value))
 
+
+@add_metaclass(class_deprecated)
 class BoxSeparator(HTMLWidget):
     """a menu separator"""
-    __metaclass__ = class_deprecated
     __deprecation_warning__ = '[3.10] class %(cls)s is deprecated'
 
     def _render(self):
         self.w(u'</ul><hr class="boxSeparator"/><ul>')
 
 
+@add_metaclass(class_deprecated)
 class BoxLink(HTMLWidget):
     """a link in a box"""
-    __metaclass__ = class_deprecated
     __deprecation_warning__ = '[3.10] class %(cls)s is deprecated'
     def __init__(self, href, label, _class='', title='', ident='', escape=False):
         self.href = href
@@ -252,9 +256,9 @@
             self.w(u'<li class="%s">%s</li>\n' % (self._class, link))
 
 
+@add_metaclass(class_deprecated)
 class BoxHtml(HTMLWidget):
     """a form in a box"""
-    __metaclass__ = class_deprecated
     __deprecation_warning__ = '[3.10] class %(cls)s is deprecated'
     def __init__(self, rawhtml):
         self.rawhtml = rawhtml
@@ -339,17 +343,17 @@
         self.w(u'<thead>')
         self.w(u'<tr class="header">')
         for column in self.columns:
-            attrs = ('%s="%s"' % (name, value) for name, value in column.cell_attrs.iteritems())
+            attrs = ('%s="%s"' % (name, value) for name, value in column.cell_attrs.items())
             self.w(u'<th %s>%s</th>' % (' '.join(attrs), column.name or u''))
         self.w(u'</tr>')
         self.w(u'</thead><tbody>')
-        for rowindex in xrange(len(self.model.get_rows())):
+        for rowindex in range(len(self.model.get_rows())):
             klass = (rowindex%2==1) and 'odd' or 'even'
             self.w(u'<tr class="%s" %s>' % (klass, self.highlight))
             for column, sortvalue in self.itercols(rowindex):
                 attrs = dict(column.cell_attrs)
                 attrs["cubicweb:sortvalue"] = sortvalue
-                attrs = ('%s="%s"' % (name, value) for name, value in attrs.iteritems())
+                attrs = ('%s="%s"' % (name, value) for name, value in attrs.items())
                 self.w(u'<td %s>' % (' '.join(attrs)))
                 for cellvid, colindex in column.cellrenderers:
                     self.model.render_cell(cellvid, rowindex, colindex, w=self.w)
@@ -361,5 +365,3 @@
     def itercols(self, rowindex):
         for column in self.columns:
             yield column, self.model.sortvalue(rowindex, column.rset_sortcol)
-
-
--- a/web/http_headers.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/http_headers.py	Thu Dec 10 12:34:15 2015 +0100
@@ -2,11 +2,14 @@
 # http://twistedmatrix.com/trac/wiki/TwistedWeb2
 
 
-import types, time
+import time
 from calendar import timegm
 import base64
 import re
-import urlparse
+
+from six import string_types
+from six.moves.urllib.parse import urlparse
+
 
 def dashCapitalize(s):
     ''' Capitalize a string, making sure to treat - as a word seperator '''
@@ -295,9 +298,9 @@
         cur = cur+1
 
     if qpair:
-        raise ValueError, "Missing character after '\\'"
+        raise ValueError("Missing character after '\\'")
     if quoted:
-        raise ValueError, "Missing end quote"
+        raise ValueError("Missing end quote")
 
     if start != cur:
         if foldCase:
@@ -347,7 +350,7 @@
 ##### parser utilities:
 def checkSingleToken(tokens):
     if len(tokens) != 1:
-        raise ValueError, "Expected single token, not %s." % (tokens,)
+        raise ValueError("Expected single token, not %s." % (tokens,))
     return tokens[0]
 
 def parseKeyValue(val):
@@ -355,11 +358,11 @@
         return val[0], None
     elif len(val) == 3 and val[1] == Token('='):
         return val[0], val[2]
-    raise ValueError, "Expected key or key=value, but got %s." % (val,)
+    raise ValueError("Expected key or key=value, but got %s." % (val,))
 
 def parseArgs(field):
     args = split(field, Token(';'))
-    val = args.next()
+    val = next(args)
     args = [parseKeyValue(arg) for arg in args]
     return val, args
 
@@ -380,7 +383,7 @@
 
 def unique(seq):
     '''if seq is not a string, check it's a sequence of one element and return it'''
-    if isinstance(seq, basestring):
+    if isinstance(seq, string_types):
         return seq
     if len(seq) != 1:
         raise ValueError('single value required, not %s' % seq)
@@ -398,7 +401,7 @@
     """Ensure origin is a valid URL-base stuff, or null"""
     if origin == 'null':
         return origin
-    p = urlparse.urlparse(origin)
+    p = urlparse(origin)
     if p.params or p.query or p.username or p.path not in ('', '/'):
         raise ValueError('Incorrect Accept-Control-Allow-Origin value %s' % origin)
     if p.scheme not in ('http', 'https'):
@@ -452,14 +455,15 @@
 
     """
     if (value in (True, 1) or
-            isinstance(value, basestring) and value.lower() == 'true'):
+            isinstance(value, string_types) and value.lower() == 'true'):
         return 'true'
     if (value in (False, 0) or
-            isinstance(value, basestring) and value.lower() == 'false'):
+            isinstance(value, string_types) and value.lower() == 'false'):
         return 'false'
     raise ValueError("Invalid true/false header value: %s" % value)
 
 class MimeType(object):
+    @classmethod
     def fromString(klass, mimeTypeString):
         """Generate a MimeType object from the given string.
 
@@ -469,8 +473,6 @@
         """
         return DefaultHTTPHandler.parse('content-type', [mimeTypeString])
 
-    fromString = classmethod(fromString)
-
     def __init__(self, mediaType, mediaSubtype, params={}, **kwargs):
         """
         @type mediaType: C{str}
@@ -499,14 +501,14 @@
         return "MimeType(%r, %r, %r)" % (self.mediaType, self.mediaSubtype, self.params)
 
     def __hash__(self):
-        return hash(self.mediaType)^hash(self.mediaSubtype)^hash(tuple(self.params.iteritems()))
+        return hash(self.mediaType)^hash(self.mediaSubtype)^hash(tuple(self.params.items()))
 
 ##### Specific header parsers.
 def parseAccept(field):
     type, args = parseArgs(field)
 
     if len(type) != 3 or type[1] != Token('/'):
-        raise ValueError, "MIME Type "+str(type)+" invalid."
+        raise ValueError("MIME Type "+str(type)+" invalid.")
 
     # okay, this spec is screwy. A 'q' parameter is used as the separator
     # between MIME parameters and (as yet undefined) additional HTTP
@@ -569,7 +571,7 @@
     type, args = parseArgs(header)
 
     if len(type) != 3 or type[1] != Token('/'):
-        raise ValueError, "MIME Type "+str(type)+" invalid."
+        raise ValueError("MIME Type "+str(type)+" invalid.")
 
     args = [(kv[0].lower(), kv[1]) for kv in args]
 
@@ -730,7 +732,7 @@
 
     out ="%s/%s"%(mimeType.mediaType, mimeType.mediaSubtype)
     if mimeType.params:
-        out+=';'+generateKeyValues(mimeType.params.iteritems())
+        out+=';'+generateKeyValues(mimeType.params.items())
 
     if q != 1.0:
         out+=(';q=%.3f' % (q,)).rstrip('0').rstrip('.')
@@ -766,7 +768,8 @@
             v = [field.strip().lower() for field in v.split(',')]
     return k, v
 
-def generateCacheControl((k, v)):
+def generateCacheControl(args):
+    k, v = args
     if v is None:
         return str(k)
     else:
@@ -833,7 +836,7 @@
 def generateContentType(mimeType):
     out = "%s/%s" % (mimeType.mediaType, mimeType.mediaSubtype)
     if mimeType.params:
-        out += ';' + generateKeyValues(mimeType.params.iteritems())
+        out += ';' + generateKeyValues(mimeType.params.items())
     return out
 
 def generateIfRange(dateOrETag):
@@ -854,7 +857,7 @@
 
         try:
             l = []
-            for k, v in dict(challenge).iteritems():
+            for k, v in dict(challenge).items():
                 l.append("%s=%s" % (k, quoteString(v)))
 
             _generated.append("%s %s" % (scheme, ", ".join(l)))
@@ -864,7 +867,7 @@
     return _generated
 
 def generateAuthorization(seq):
-    return [' '.join(seq)]
+    return [' '.join(str(v) for v in seq)]
 
 
 ####
@@ -1326,10 +1329,10 @@
         self._headers = {}
         self.handler = handler
         if headers is not None:
-            for key, value in headers.iteritems():
+            for key, value in headers.items():
                 self.setHeader(key, value)
         if rawHeaders is not None:
-            for key, value in rawHeaders.iteritems():
+            for key, value in rawHeaders.items():
                 self.setRawHeaders(key, value)
 
     def _setRawHeaders(self, headers):
@@ -1458,7 +1461,7 @@
         """Return an iterator of key, value pairs of all headers
         contained in this object, as strings. The keys are capitalized
         in canonical capitalization."""
-        for k, v in self._raw_headers.iteritems():
+        for k, v in self._raw_headers.items():
             if v is _RecalcNeeded:
                 v = self._toRaw(k)
             yield self.canonicalNameCaps(k), v
@@ -1480,7 +1483,7 @@
    is strictly an error, but we're nice.).
    """
 
-iteritems = lambda x: x.iteritems()
+iteritems = lambda x: x.items()
 
 
 parser_general_headers = {
--- a/web/httpcache.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/httpcache.py	Thu Dec 10 12:34:15 2015 +0100
@@ -31,6 +31,7 @@
 
     def set_headers(self):
         self.req.set_header('Cache-control', 'no-cache')
+        self.req.set_header('Expires', 'Sat, 01 Jan 2000 00:00:00 GMT')
 
 
 class MaxAgeHTTPCacheManager(NoHTTPCacheManager):
@@ -68,7 +69,7 @@
         try:
             req.set_header('Etag', '"%s"' % self.etag())
         except NoEtag:
-            self.req.set_header('Cache-control', 'no-cache')
+            super(EtagHTTPCacheManager, self).set_headers()
             return
         req.set_header('Cache-control',
                        'must-revalidate,max-age=%s' % self.max_age())
@@ -178,4 +179,3 @@
     ('if-none-match', if_none_match),
     #('if-modified-since', if_modified_since),
 ]
-
--- a/web/propertysheet.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/propertysheet.py	Thu Dec 10 12:34:15 2015 +0100
@@ -22,6 +22,8 @@
 import re
 import os
 import os.path as osp
+import tempfile
+
 
 TYPE_CHECKS = [('STYLESHEETS', list), ('JAVASCRIPTS', list),
                ('STYLESHEETS_IE', list), ('STYLESHEETS_PRINT', list),
@@ -51,13 +53,13 @@
         self.clear()
         self._ordered_propfiles = []
         self._propfile_mtime = {}
-        self._sourcefile_mtime = {}
-        self._cache = {}
 
     def load(self, fpath):
         scriptglobals = self.context.copy()
         scriptglobals['__file__'] = fpath
-        execfile(fpath, scriptglobals, self)
+        with open(fpath, 'rb') as fobj:
+            code = compile(fobj.read(), fpath, 'exec')
+        exec(code, scriptglobals, self)
         for name, type in TYPE_CHECKS:
             if name in self:
                 if not isinstance(self[name], type):
@@ -67,10 +69,7 @@
         self._ordered_propfiles.append(fpath)
 
     def need_reload(self):
-        for rid, (adirectory, rdirectory, mtime) in self._cache.items():
-            if os.stat(osp.join(rdirectory, rid)).st_mtime > mtime:
-                del self._cache[rid]
-        for fpath, mtime in self._propfile_mtime.iteritems():
+        for fpath, mtime in self._propfile_mtime.items():
             if os.stat(fpath).st_mtime > mtime:
                 return True
         return False
@@ -86,31 +85,29 @@
             self.reload()
 
     def process_resource(self, rdirectory, rid):
+        cachefile = osp.join(self._cache_directory, rid)
+        self.debug('processing %s/%s into %s',
+                   rdirectory, rid, cachefile)
+        rcachedir = osp.dirname(cachefile)
+        if not osp.exists(rcachedir):
+            os.makedirs(rcachedir)
+        sourcefile = osp.join(rdirectory, rid)
+        with open(sourcefile) as f:
+            content = f.read()
+        # XXX replace % not followed by a paren by %% to avoid having to do
+        # this in the source css file ?
         try:
-            return self._cache[rid][0]
-        except KeyError:
-            cachefile = osp.join(self._cache_directory, rid)
-            self.debug('caching processed %s/%s into %s',
-                       rdirectory, rid, cachefile)
-            rcachedir = osp.dirname(cachefile)
-            if not osp.exists(rcachedir):
-                os.makedirs(rcachedir)
-            sourcefile = osp.join(rdirectory, rid)
-            content = file(sourcefile).read()
-            # XXX replace % not followed by a paren by %% to avoid having to do
-            # this in the source css file ?
-            try:
-                content = self.compile(content)
-            except ValueError as ex:
-                self.error("can't process %s/%s: %s", rdirectory, rid, ex)
-                adirectory = rdirectory
-            else:
-                stream = file(cachefile, 'w')
+            content = self.compile(content)
+        except ValueError as ex:
+            self.error("can't process %s/%s: %s", rdirectory, rid, ex)
+            adirectory = rdirectory
+        else:
+            tmpfd, tmpfile = tempfile.mkstemp(dir=rcachedir, prefix=osp.basename(cachefile))
+            with os.fdopen(tmpfd, 'w') as stream:
                 stream.write(content)
-                stream.close()
-                adirectory = self._cache_directory
-            self._cache[rid] = (adirectory, rdirectory, os.stat(sourcefile).st_mtime)
-            return adirectory
+            os.rename(tmpfile, cachefile)
+            adirectory = self._cache_directory
+        return adirectory
 
     def compile(self, content):
         return self._percent_rgx.sub('%%', content) % self
--- a/web/request.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/request.py	Thu Dec 10 12:34:15 2015 +0100
@@ -22,15 +22,16 @@
 import time
 import random
 import base64
-import urllib
-from StringIO import StringIO
 from hashlib import sha1 # pylint: disable=E0611
-from Cookie import SimpleCookie
 from calendar import timegm
 from datetime import date, datetime
-from urlparse import urlsplit
-import httplib
 from warnings import warn
+from io import BytesIO
+
+from six import PY2, binary_type, text_type, string_types
+from six.moves import http_client
+from six.moves.urllib.parse import urlsplit, quote as urlquote
+from six.moves.http_cookies import SimpleCookie
 
 from rql.utils import rqlvar_maker
 
@@ -41,7 +42,7 @@
 from cubicweb import AuthenticationError
 from cubicweb.req import RequestSessionBase
 from cubicweb.uilib import remove_html_tags, js
-from cubicweb.utils import SizeConstrainedList, HTMLHead, make_uid
+from cubicweb.utils import HTMLHead, make_uid
 from cubicweb.view import TRANSITIONAL_DOCTYPE_NOEXT
 from cubicweb.web import (INTERNAL_FIELD_VALUE, LOGGER, NothingToEdit,
                           RequestError, StatusResponse)
@@ -51,7 +52,7 @@
 _MARKER = object()
 
 def build_cb_uid(seed):
-    sha = sha1('%s%s%s' % (time.time(), seed, random.random()))
+    sha = sha1(('%s%s%s' % (time.time(), seed, random.random())).encode('ascii'))
     return 'cb_%s' % (sha.hexdigest())
 
 
@@ -137,12 +138,12 @@
         #: received headers
         self._headers_in = Headers()
         if headers is not None:
-            for k, v in headers.iteritems():
+            for k, v in headers.items():
                 self._headers_in.addRawHeader(k, v)
         #: form parameters
         self.setup_params(form)
         #: received body
-        self.content = StringIO()
+        self.content = BytesIO()
         # prepare output header
         #: Header used for the final response
         self.headers_out = Headers()
@@ -242,7 +243,7 @@
                                  '__redirectvid', '__redirectrql'))
 
     def setup_params(self, params):
-        """WARNING: we're intentionaly leaving INTERNAL_FIELD_VALUE here
+        """WARNING: we're intentionally leaving INTERNAL_FIELD_VALUE here
 
         subclasses should overrides to
         """
@@ -250,12 +251,13 @@
         if params is None:
             return
         encoding = self.encoding
-        for param, val in params.iteritems():
+        for param, val in params.items():
             if isinstance(val, (tuple, list)):
-                val = [unicode(x, encoding) for x in val]
+                if PY2:
+                    val = [unicode(x, encoding) for x in val]
                 if len(val) == 1:
                     val = val[0]
-            elif isinstance(val, str):
+            elif PY2 and isinstance(val, str):
                 val = unicode(val, encoding)
             if param in self.no_script_form_params and val:
                 val = self.no_script_form_param(param, val)
@@ -317,7 +319,7 @@
                 return None
 
     def set_message(self, msg):
-        assert isinstance(msg, unicode)
+        assert isinstance(msg, text_type)
         self.reset_message()
         self._msg = msg
 
@@ -330,7 +332,7 @@
 
     def set_redirect_message(self, msg):
         # TODO - this should probably be merged with append_to_redirect_message
-        assert isinstance(msg, unicode)
+        assert isinstance(msg, text_type)
         msgid = self.redirect_message_id()
         self.session.data[msgid] = msg
         return msgid
@@ -396,26 +398,6 @@
                 return False
         return True
 
-    def update_breadcrumbs(self):
-        """stores the last visisted page in session data"""
-        searchstate = self.search_state[0]
-        if searchstate == 'normal':
-            breadcrumbs = self.session.data.get('breadcrumbs')
-            if breadcrumbs is None:
-                breadcrumbs = SizeConstrainedList(10)
-                self.session.data['breadcrumbs'] = breadcrumbs
-                breadcrumbs.append(self.url())
-            else:
-                url = self.url()
-                if breadcrumbs and breadcrumbs[-1] != url:
-                    breadcrumbs.append(url)
-
-    def last_visited_page(self):
-        breadcrumbs = self.session.data.get('breadcrumbs')
-        if breadcrumbs:
-            return breadcrumbs.pop()
-        return self.base_url()
-
     # web edition helpers #####################################################
 
     @cached # so it's writed only once
@@ -437,7 +419,7 @@
             eids = form['eid']
         except KeyError:
             raise NothingToEdit(self._('no selected entities'))
-        if isinstance(eids, basestring):
+        if isinstance(eids, string_types):
             eids = (eids,)
         for peid in eids:
             if withtype:
@@ -569,18 +551,18 @@
             header = [disposition]
             unicode_filename = None
             try:
-                ascii_filename = filename.encode('ascii')
+                ascii_filename = filename.encode('ascii').decode('ascii')
             except UnicodeEncodeError:
                 # fallback filename for very old browser
                 unicode_filename = filename
-                ascii_filename = filename.encode('ascii', 'ignore')
+                ascii_filename = filename.encode('ascii', 'ignore').decode('ascii')
             # escape " and \
             # see http://greenbytes.de/tech/tc2231/#attwithfilenameandextparamescaped
             ascii_filename = ascii_filename.replace('\x5c', r'\\').replace('"', r'\"')
             header.append('filename="%s"' % ascii_filename)
             if unicode_filename is not None:
                 # encoded filename according RFC5987
-                urlquoted_filename = urllib.quote(unicode_filename.encode('utf-8'), '')
+                urlquoted_filename = urlquote(unicode_filename.encode('utf-8'), '')
                 header.append("filename*=utf-8''" + urlquoted_filename)
             self.set_header('content-disposition', ';'.join(header))
 
@@ -596,7 +578,7 @@
         :param localfile: if True, the default data dir prefix is added to the
                           JS filename
         """
-        if isinstance(jsfiles, basestring):
+        if isinstance(jsfiles, string_types):
             jsfiles = (jsfiles,)
         for jsfile in jsfiles:
             if localfile:
@@ -616,7 +598,7 @@
                        the css inclusion. cf:
                        http://msdn.microsoft.com/en-us/library/ms537512(VS.85).aspx
         """
-        if isinstance(cssfiles, basestring):
+        if isinstance(cssfiles, string_types):
             cssfiles = (cssfiles,)
         if ieonly:
             if self.ie_browser():
@@ -702,7 +684,7 @@
         return urlsplit(self.base_url())[2]
 
     def data_url(self, relpath):
-        """returns the absolute path for a data resouce"""
+        """returns the absolute path for a data resource"""
         return self.datadir_url + relpath
 
     @cached
@@ -722,25 +704,19 @@
         Some response cache headers may be set by this method.
         """
         modified = True
-        if self.get_header('Cache-Control') not in ('max-age=0', 'no-cache'):
-            # Here, we search for any invalid 'not modified' condition
-            # see http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.3
-            validators = get_validators(self._headers_in)
-            if validators: # if we have no
-                modified = any(func(val, self.headers_out) for func, val in validators)
+        # Here, we search for any invalid 'not modified' condition
+        # see http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.3
+        validators = get_validators(self._headers_in)
+        if validators: # if we have no
+            modified = any(func(val, self.headers_out) for func, val in validators)
         # Forge expected response
-        if modified:
-            if 'Expires' not in self.headers_out:
-                # Expires header seems to be required by IE7 -- Are you sure ?
-                self.add_header('Expires', 'Sat, 01 Jan 2000 00:00:00 GMT')
-            # /!\ no raise, the function returns and we keep processing the request
-        else:
+        if not modified:
             # overwrite headers_out to forge a brand new not-modified response
             self.headers_out = self._forge_cached_headers()
             if self.http_method() in ('HEAD', 'GET'):
-                self.status_out = httplib.NOT_MODIFIED
+                self.status_out = http_client.NOT_MODIFIED
             else:
-                self.status_out = httplib.PRECONDITION_FAILED
+                self.status_out = http_client.PRECONDITION_FAILED
             # XXX replace by True once validate_cache bw compat method is dropped
             return self.status_out
         # XXX replace by False once validate_cache bw compat method is dropped
@@ -800,7 +776,7 @@
     def header_accept_language(self):
         """returns an ordered list of preferred languages"""
         acceptedlangs = self.get_header('Accept-Language', raw=False) or {}
-        for lang, _ in sorted(acceptedlangs.iteritems(), key=lambda x: x[1],
+        for lang, _ in sorted(acceptedlangs.items(), key=lambda x: x[1],
                               reverse=True):
             lang = lang.split('-')[0]
             yield lang
@@ -844,7 +820,7 @@
             scheme = scheme.lower()
             try:
                 assert scheme == "basic"
-                user, passwd = base64.decodestring(rest).split(":", 1)
+                user, passwd = base64.decodestring(rest.encode('ascii')).split(b":", 1)
                 # XXX HTTP header encoding: use email.Header?
                 return user.decode('UTF8'), passwd
             except Exception as ex:
@@ -966,8 +942,10 @@
     def __getattribute__(self, attr):
         raise AuthenticationError()
 
-    def __nonzero__(self):
+    def __bool__(self):
         return False
+    
+    __nonzero__ = __bool__
 
 class _MockAnonymousSession(object):
     sessionid = 'thisisnotarealsession'
@@ -1023,8 +1001,8 @@
             self.set_language(lang)
         except KeyError:
             # this occurs usually during test execution
-            self._ = self.__ = unicode
-            self.pgettext = lambda x, y: unicode(y)
+            self._ = self.__ = text_type
+            self.pgettext = lambda x, y: text_type(y)
 
     entity_metas = _cnx_func('entity_metas')
     source_defs = _cnx_func('source_defs')
--- a/web/schemaviewer.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/schemaviewer.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,7 +18,9 @@
 """an helper class to display CubicWeb schema using ureports"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
+
+from six import string_types
 
 from logilab.common.ureports import Section, Title, Table, Link, Span, Text
 
@@ -218,7 +220,7 @@
                     elif prop == 'constraints':
                         val = ', '.join([c.expression for c in val])
                     elif isinstance(val, dict):
-                        for key, value in val.iteritems():
+                        for key, value in val.items():
                             if isinstance(value, (list, tuple)):
                                 val[key] = ', '.join(sorted( str(v) for v in value))
                         val = str(val)
@@ -226,7 +228,7 @@
                     elif isinstance(val, (list, tuple)):
                         val = sorted(val)
                         val = ', '.join(str(v) for v in val)
-                    elif val and isinstance(val, basestring):
+                    elif val and isinstance(val, string_types):
                         val = _(val)
                     else:
                         val = str(val)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/test/data/static/jstests/ajax_url0.html	Thu Dec 10 12:34:15 2015 +0100
@@ -0,0 +1,3 @@
+<div id="ajaxroot">
+  <h1>Hello</h1>
+</div>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/test/data/static/jstests/ajax_url1.html	Thu Dec 10 12:34:15 2015 +0100
@@ -0,0 +1,6 @@
+<div id="ajaxroot">
+  <div class="ajaxHtmlHead">
+    <cubicweb:script src="http://foo.js" type="text/javascript"> </cubicweb:script>
+  </div>
+  <h1>Hello</h1>
+</div>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/test/data/static/jstests/ajaxresult.json	Thu Dec 10 12:34:15 2015 +0100
@@ -0,0 +1,1 @@
+["foo", "bar"]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/test/data/static/jstests/test_ajax.html	Thu Dec 10 12:34:15 2015 +0100
@@ -0,0 +1,26 @@
+<html>
+  <head>
+    <!-- dependencies -->
+    <script type="text/javascript">
+      var JSON_BASE_URL = '';
+    </script>
+    <script type="text/javascript" src="/data/jquery.js"></script>
+    <script src="/data/cubicweb.js" type="text/javascript"></script>
+    <script src="/data/cubicweb.htmlhelpers.js" type="text/javascript"></script>
+    <script src="/data/cubicweb.python.js" type="text/javascript"></script>
+    <script src="/data/cubicweb.compat.js" type="text/javascript"></script>
+    <script src="/data/cubicweb.ajax.js" type="text/javascript"></script>
+    <!-- qunit files -->
+    <script type="text/javascript" src="/devtools/qunit.js"></script>
+    <link rel="stylesheet" type="text/css" media="all" href="/devtools/qunit.css" />
+    <!-- test suite -->
+    <script src="/devtools/cwmock.js" type="text/javascript"></script>
+    <script src="test_ajax.js" type="text/javascript"></script>
+  </head>
+  <body>
+    <div id="main"> </div>
+    <h1 id="qunit-header">cubicweb.ajax.js functions tests</h1>
+    <h2 id="qunit-banner"></h2>
+    <ol id="qunit-tests">
+  </body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/test/data/static/jstests/test_ajax.js	Thu Dec 10 12:34:15 2015 +0100
@@ -0,0 +1,274 @@
+$(document).ready(function() {
+
+    QUnit.module("ajax", {
+        setup: function() {
+          this.scriptsLength = $('head script[src]').length-1;
+          this.cssLength = $('head link[rel=stylesheet]').length-1;
+          // re-initialize cw loaded cache so that each tests run in a
+          // clean environment, have a lookt at _loadAjaxHtmlHead implementation
+          // in cubicweb.ajax.js for more information.
+          cw.loaded_scripts = [];
+          cw.loaded_links = [];
+        },
+        teardown: function() {
+          $('head script[src]:lt(' + ($('head script[src]').length - 1 - this.scriptsLength) + ')').remove();
+          $('head link[rel=stylesheet]:gt(' + this.cssLength + ')').remove();
+        }
+      });
+
+    function jsSources() {
+        return $.map($('head script[src]'), function(script) {
+            return script.getAttribute('src');
+        });
+    }
+
+    QUnit.test('test simple h1 inclusion (ajax_url0.html)', function (assert) {
+        assert.expect(3);
+        assert.equal($('#qunit-fixture').children().length, 0);
+        var done = assert.async();
+        $('#qunit-fixture').loadxhtml('static/jstests/ajax_url0.html', null, 'GET')
+        .addCallback(function() {
+                try {
+                    assert.equal($('#qunit-fixture').children().length, 1);
+                    assert.equal($('#qunit-fixture h1').html(), 'Hello');
+                } finally {
+                    done();
+                };
+            }
+        );
+    });
+
+    QUnit.test('test simple html head inclusion (ajax_url1.html)', function (assert) {
+        assert.expect(6);
+        var scriptsIncluded = jsSources();
+        assert.equal(jQuery.inArray('http://foo.js', scriptsIncluded), - 1);
+        var done = assert.async();
+        $('#qunit-fixture').loadxhtml('static/jstests/ajax_url1.html', null, 'GET')
+        .addCallback(function() {
+                try {
+                    var origLength = scriptsIncluded.length;
+                    scriptsIncluded = jsSources();
+                    // check that foo.js has been prepended to <head>
+                    assert.equal(scriptsIncluded.length, origLength + 1);
+                    assert.equal(scriptsIncluded.indexOf('http://foo.js'), 0);
+                    // check that <div class="ajaxHtmlHead"> has been removed
+                    assert.equal($('#qunit-fixture').children().length, 1);
+                    assert.equal($('div.ajaxHtmlHead').length, 0);
+                    assert.equal($('#qunit-fixture h1').html(), 'Hello');
+                } finally {
+                    done();
+                };
+            }
+        );
+    });
+
+    QUnit.test('test addCallback', function (assert) {
+        assert.expect(3);
+        assert.equal($('#qunit-fixture').children().length, 0);
+        var done = assert.async();
+        var d = $('#qunit-fixture').loadxhtml('static/jstests/ajax_url0.html', null, 'GET');
+        d.addCallback(function() {
+            try {
+                assert.equal($('#qunit-fixture').children().length, 1);
+                assert.equal($('#qunit-fixture h1').html(), 'Hello');
+            } finally {
+                done();
+            };
+        });
+    });
+
+    QUnit.test('test callback after synchronous request', function (assert) {
+        assert.expect(1);
+        var deferred = new Deferred();
+        var result = jQuery.ajax({
+            url: 'static/jstests/ajax_url0.html',
+            async: false,
+            beforeSend: function(xhr) {
+                deferred._req = xhr;
+            },
+            success: function(data, status) {
+                deferred.success(data);
+            }
+        });
+        var done = assert.async();
+        deferred.addCallback(function() {
+            try {
+                // add an assertion to ensure the callback is executed
+                assert.ok(true, "callback is executed");
+            } finally {
+                done();
+            };
+        });
+    });
+
+    QUnit.test('test addCallback with parameters', function (assert) {
+        assert.expect(3);
+        assert.equal($('#qunit-fixture').children().length, 0);
+        var done = assert.async();
+        var d = $('#qunit-fixture').loadxhtml('static/jstests/ajax_url0.html', null, 'GET');
+        d.addCallback(function(data, req, arg1, arg2) {
+            try {
+                assert.equal(arg1, 'Hello');
+                assert.equal(arg2, 'world');
+            } finally {
+                done();
+            };
+        },
+        'Hello', 'world');
+    });
+
+    QUnit.test('test callback after synchronous request with parameters', function (assert) {
+        assert.expect(3);
+        var deferred = new Deferred();
+        deferred.addCallback(function(data, req, arg1, arg2) {
+            // add an assertion to ensure the callback is executed
+            try {
+                assert.ok(true, "callback is executed");
+                assert.equal(arg1, 'Hello');
+                assert.equal(arg2, 'world');
+            } finally {
+                done();
+            };
+        },
+        'Hello', 'world');
+        deferred.addErrback(function() {
+            // throw an exception to start errback chain
+            try {
+                throw this._error;
+            } finally {
+                done();
+            };
+        });
+        var done = assert.async();
+        var result = jQuery.ajax({
+            url: 'static/jstests/ajax_url0.html',
+            async: false,
+            beforeSend: function(xhr) {
+                deferred._req = xhr;
+            },
+            success: function(data, status) {
+                deferred.success(data);
+            }
+        });
+    });
+
+  QUnit.test('test addErrback', function (assert) {
+        assert.expect(1);
+        var done = assert.async();
+        var d = $('#qunit-fixture').loadxhtml('static/jstests/nonexistent.html', null, 'GET');
+        d.addCallback(function() {
+            // should not be executed
+            assert.ok(false, "callback is executed");
+        });
+        d.addErrback(function() {
+            try {
+                assert.ok(true, "errback is executed");
+            } finally {
+                done();
+            };
+        });
+    });
+
+    QUnit.test('test callback execution order', function (assert) {
+        assert.expect(3);
+        var counter = 0;
+        var done = assert.async();
+        var d = $('#qunit-fixture').loadxhtml('static/jstests/ajax_url0.html', null, 'GET');
+        d.addCallback(function() {
+            assert.equal(++counter, 1); // should be executed first
+        });
+        d.addCallback(function() {
+            assert.equal(++counter, 2);
+        });
+        d.addCallback(function() {
+            try {
+                assert.equal(++counter, 3);
+            } finally {
+                done();
+            }
+        });
+    });
+
+    QUnit.test('test already included resources are ignored (ajax_url1.html)', function (assert) {
+        assert.expect(10);
+        var scriptsIncluded = jsSources();
+        // NOTE:
+        assert.equal(jQuery.inArray('http://foo.js', scriptsIncluded), -1);
+        assert.equal($('head link').length, 1);
+        /* use endswith because in pytest context we have an absolute path */
+        assert.ok($('head link').attr('href').endswith('/qunit.css'), 'qunit.css is loaded');
+        var done = assert.async();
+        $('#qunit-fixture').loadxhtml('static/jstests/ajax_url1.html', null, 'GET')
+        .addCallback(function() {
+                var origLength = scriptsIncluded.length;
+                scriptsIncluded = jsSources();
+                try {
+                    // check that foo.js has been inserted in <head>
+                    assert.equal(scriptsIncluded.length, origLength + 1);
+                    assert.equal(scriptsIncluded.indexOf('http://foo.js'), 0);
+                    // check that <div class="ajaxHtmlHead"> has been removed
+                    assert.equal($('#qunit-fixture').children().length, 1);
+                    assert.equal($('div.ajaxHtmlHead').length, 0);
+                    assert.equal($('#qunit-fixture h1').html(), 'Hello');
+                    // qunit.css is not added twice
+                    assert.equal($('head link').length, 1);
+                    /* use endswith because in pytest context we have an absolute path */
+                    assert.ok($('head link').attr('href').endswith('/qunit.css'), 'qunit.css is loaded');
+                } finally {
+                    done();
+                }
+            }
+        );
+    });
+
+    QUnit.test('test synchronous request loadRemote', function (assert) {
+        var res = loadRemote('static/jstests/ajaxresult.json', {},
+        'GET', true);
+        assert.deepEqual(res, ['foo', 'bar']);
+    });
+
+    QUnit.test('test event on CubicWeb', function (assert) {
+        assert.expect(1);
+        var done = assert.async();
+        var events = null;
+        $(CubicWeb).bind('server-response', function() {
+            // check that server-response event on CubicWeb is triggered
+            events = 'CubicWeb';
+        });
+        $('#qunit-fixture').loadxhtml('static/jstests/ajax_url0.html', null, 'GET')
+        .addCallback(function() {
+                try {
+                    assert.equal(events, 'CubicWeb');
+                } finally {
+                    done();
+                };
+            }
+        );
+    });
+
+    QUnit.test('test event on node', function (assert) {
+        assert.expect(3);
+        var done = assert.async();
+        var nodes = [];
+        $('#qunit-fixture').bind('server-response', function() {
+            nodes.push('node');
+        });
+        $(CubicWeb).bind('server-response', function() {
+            nodes.push('CubicWeb');
+        });
+        $('#qunit-fixture').loadxhtml('static/jstests/ajax_url0.html', null, 'GET')
+        .addCallback(function() {
+                try {
+                    assert.equal(nodes.length, 2);
+                    // check that server-response event on CubicWeb is triggered
+                    // only once and event server-response on node is triggered
+                    assert.equal(nodes[0], 'CubicWeb');
+                    assert.equal(nodes[1], 'node');
+                } finally {
+                    done();
+                };
+            }
+        );
+    });
+});
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/test/data/static/jstests/test_htmlhelpers.html	Thu Dec 10 12:34:15 2015 +0100
@@ -0,0 +1,22 @@
+<html>
+  <head>
+    <!-- dependencies -->
+    <script type="text/javascript" src="../../data/jquery.js"></script>
+    <script src="../../data/cubicweb.python.js" type="text/javascript"></script>
+    <script src="../../data/cubicweb.js" type="text/javascript"></script>
+    <script src="../../data/cubicweb.compat.js" type="text/javascript"></script>
+    <script src="../../data/cubicweb.htmlhelpers.js" type="text/javascript"></script>
+    <!-- qunit files -->
+    <script type="text/javascript" src="../../../devtools/data/qunit.js"></script>
+    <link rel="stylesheet" type="text/css" media="all" href="../../../devtools/data/qunit.css" />
+    <!-- test suite -->
+    <script src="cwmock.js" type="text/javascript"></script>
+    <script src="test_htmlhelpers.js" type="text/javascript"></script>
+  </head>
+  <body>
+    <div id="main"> </div>
+    <h1 id="qunit-header">cubicweb.htmlhelpers.js functions tests</h1>
+    <h2 id="qunit-banner"></h2>
+    <ol id="qunit-tests">
+  </body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/test/data/static/jstests/test_htmlhelpers.js	Thu Dec 10 12:34:15 2015 +0100
@@ -0,0 +1,36 @@
+$(document).ready(function() {
+
+    QUnit.module("module2", {
+      setup: function() {
+        $('#qunit-fixture').append('<select id="theselect" multiple="multiple" size="2">' +
+    			'</select>');
+      }
+    });
+
+    QUnit.test("test first selected", function (assert) {
+        $('#theselect').append('<option value="foo">foo</option>' +
+    			     '<option selected="selected" value="bar">bar</option>' +
+    			     '<option value="baz">baz</option>' +
+    			     '<option selected="selecetd"value="spam">spam</option>');
+        var selected = firstSelected(document.getElementById("theselect"));
+        assert.equal(selected.value, 'bar');
+    });
+
+    QUnit.test("test first selected 2", function (assert) {
+        $('#theselect').append('<option value="foo">foo</option>' +
+    			     '<option value="bar">bar</option>' +
+    			     '<option value="baz">baz</option>' +
+    			     '<option value="spam">spam</option>');
+        var selected = firstSelected(document.getElementById("theselect"));
+        assert.equal(selected, null);
+    });
+
+    QUnit.module("visibilty");
+    QUnit.test('toggleVisibility', function (assert) {
+        $('#qunit-fixture').append('<div id="foo"></div>');
+        toggleVisibility('foo');
+        assert.ok($('#foo').hasClass('hidden'), 'check hidden class is set');
+    });
+
+});
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/test/data/static/jstests/test_utils.html	Thu Dec 10 12:34:15 2015 +0100
@@ -0,0 +1,22 @@
+<html>
+  <head>
+    <!-- dependencies -->
+    <script type="text/javascript" src="utils.js"></script>
+    <script type="text/javascript" src="../../data/jquery.js"></script>
+    <script src="../../data/cubicweb.python.js" type="text/javascript"></script>
+    <script src="../../data/cubicweb.js" type="text/javascript"></script>
+    <script src="../../data/cubicweb.compat.js" type="text/javascript"></script>
+    <!-- qunit files -->
+    <script type="text/javascript" src="../../../devtools/data/qunit.js"></script>
+    <link rel="stylesheet" type="text/css" media="all" href="../../../devtools/data/qunit.css" />
+    <!-- test suite -->
+    <script src="cwmock.js" type="text/javascript"></script>
+    <script src="test_utils.js" type="text/javascript"></script>
+  </head>
+  <body>
+    <div id="main"> </div>
+    <h1 id="qunit-header">cw.utils functions tests</h1>
+    <h2 id="qunit-banner"></h2>
+    <ol id="qunit-tests">
+  </body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/test/data/static/jstests/test_utils.js	Thu Dec 10 12:34:15 2015 +0100
@@ -0,0 +1,92 @@
+$(document).ready(function() {
+
+  QUnit.module("datetime");
+
+  QUnit.test("test full datetime", function (assert) {
+      assert.equal(cw.utils.toISOTimestamp(new Date(1986, 3, 18, 10, 30, 0, 0)),
+	     '1986-04-18 10:30:00');
+  });
+
+  QUnit.test("test only date", function (assert) {
+      assert.equal(cw.utils.toISOTimestamp(new Date(1986, 3, 18)), '1986-04-18 00:00:00');
+  });
+
+  QUnit.test("test null", function (assert) {
+      assert.equal(cw.utils.toISOTimestamp(null), null);
+  });
+
+  QUnit.module("parsing");
+  QUnit.test("test basic number parsing", function (assert) {
+      var d = strptime('2008/08/08', '%Y/%m/%d');
+      assert.deepEqual(datetuple(d), [2008, 8, 8, 0, 0]);
+      d = strptime('2008/8/8', '%Y/%m/%d');
+      assert.deepEqual(datetuple(d), [2008, 8, 8, 0, 0]);
+      d = strptime('8/8/8', '%Y/%m/%d');
+      assert.deepEqual(datetuple(d), [8, 8, 8, 0, 0]);
+      d = strptime('0/8/8', '%Y/%m/%d');
+      assert.deepEqual(datetuple(d), [0, 8, 8, 0, 0]);
+      d = strptime('-10/8/8', '%Y/%m/%d');
+      assert.deepEqual(datetuple(d), [-10, 8, 8, 0, 0]);
+      d = strptime('-35000', '%Y');
+      assert.deepEqual(datetuple(d), [-35000, 1, 1, 0, 0]);
+  });
+
+  QUnit.test("test custom format parsing", function (assert) {
+      var d = strptime('2008-08-08', '%Y-%m-%d');
+      assert.deepEqual(datetuple(d), [2008, 8, 8, 0, 0]);
+      d = strptime('2008 - !  08: 08', '%Y - !  %m: %d');
+      assert.deepEqual(datetuple(d), [2008, 8, 8, 0, 0]);
+      d = strptime('2008-08-08 12:14', '%Y-%m-%d %H:%M');
+      assert.deepEqual(datetuple(d), [2008, 8, 8, 12, 14]);
+      d = strptime('2008-08-08 1:14', '%Y-%m-%d %H:%M');
+      assert.deepEqual(datetuple(d), [2008, 8, 8, 1, 14]);
+      d = strptime('2008-08-08 01:14', '%Y-%m-%d %H:%M');
+      assert.deepEqual(datetuple(d), [2008, 8, 8, 1, 14]);
+  });
+
+  QUnit.module("sliceList");
+  QUnit.test("test slicelist", function (assert) {
+      var list = ['a', 'b', 'c', 'd', 'e', 'f'];
+      assert.deepEqual(cw.utils.sliceList(list, 2),  ['c', 'd', 'e', 'f']);
+      assert.deepEqual(cw.utils.sliceList(list, 2, -2), ['c', 'd']);
+      assert.deepEqual(cw.utils.sliceList(list, -3), ['d', 'e', 'f']);
+      assert.deepEqual(cw.utils.sliceList(list, 0, -2), ['a', 'b', 'c', 'd']);
+      assert.deepEqual(cw.utils.sliceList(list),  list);
+  });
+
+  QUnit.module("formContents", {
+    setup: function() {
+      $('#qunit-fixture').append('<form id="test-form"></form>');
+    }
+  });
+  // XXX test fckeditor
+  QUnit.test("test formContents", function (assert) {
+      $('#test-form').append('<input name="input-text" ' +
+			     'type="text" value="toto" />');
+      $('#test-form').append('<textarea rows="10" cols="30" '+
+			     'name="mytextarea">Hello World!</textarea> ');
+      $('#test-form').append('<input name="choice" type="radio" ' +
+			     'value="yes" />');
+      $('#test-form').append('<input name="choice" type="radio" ' +
+			     'value="no" checked="checked"/>');
+      $('#test-form').append('<input name="check" type="checkbox" ' +
+			     'value="yes" />');
+      $('#test-form').append('<input name="check" type="checkbox" ' +
+			     'value="no" checked="checked"/>');
+      $('#test-form').append('<select id="theselect" name="theselect" ' +
+			     'multiple="multiple" size="2"></select>');
+      $('#theselect').append('<option selected="selected" ' +
+			     'value="foo">foo</option>' +
+  			     '<option value="bar">bar</option>');
+      //Append an unchecked radio input : should not be in formContents list
+      $('#test-form').append('<input name="unchecked-choice" type="radio" ' +
+			     'value="one" />');
+      $('#test-form').append('<input name="unchecked-choice" type="radio" ' +
+			     'value="two"/>');
+      assert.deepEqual(cw.utils.formContents($('#test-form')[0]), [
+	['input-text', 'mytextarea', 'choice', 'check', 'theselect'],
+	['toto', 'Hello World!', 'no', 'no', 'foo']
+      ]);
+  });
+});
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/test/data/static/jstests/utils.js	Thu Dec 10 12:34:15 2015 +0100
@@ -0,0 +1,29 @@
+function datetuple(d) {
+    return [d.getFullYear(), d.getMonth()+1, d.getDate(),
+	    d.getHours(), d.getMinutes()];
+}
+
+function pprint(obj) {
+    print('{');
+    for(k in obj) {
+	print('  ' + k + ' = ' + obj[k]);
+    }
+    print('}');
+}
+
+function arrayrepr(array) {
+    return '[' + array.join(', ') + ']';
+}
+
+function assertArrayEquals(array1, array2) {
+    if (array1.length != array2.length) {
+	throw new crosscheck.AssertionFailure(array1.join(', ') + ' != ' + array2.join(', '));
+    }
+    for (var i=0; i<array1.length; i++) {
+	if (array1[i] != array2[i]) {
+
+	    throw new crosscheck.AssertionFailure(arrayrepr(array1) + ' and ' + arrayrepr(array2)
+						 + ' differs at index ' + i);
+	}
+    }
+}
--- a/web/test/data/views.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/test/data/views.py	Thu Dec 10 12:34:15 2015 +0100
@@ -42,10 +42,10 @@
     """
     try:
         result_dict = {}
-        for key, value in self._cw.form.iteritems():
+        for key, value in self._cw.form.items():
             result_dict[key] = _recursive_replace_stream_by_content(value)
         return result_dict
-    except Exception, ex:
+    except Exception as ex:
         import traceback as tb
         tb.print_exc(ex)
 
--- a/web/test/jstests/ajax_url0.html	Wed Dec 09 18:42:13 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<div id="ajaxroot">
-  <h1>Hello</h1>
-</div>
--- a/web/test/jstests/ajax_url1.html	Wed Dec 09 18:42:13 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-<div id="ajaxroot">
-  <div class="ajaxHtmlHead">
-    <cubicweb:script src="http://foo.js" type="text/javascript"> </cubicweb:script>
-  </div>
-  <h1>Hello</h1>
-</div>
--- a/web/test/jstests/ajax_url2.html	Wed Dec 09 18:42:13 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-<div id="ajaxroot">
-  <div class="ajaxHtmlHead">
-    <script src="http://foo.js" type="text/javascript"> </script>
-    <link rel="stylesheet" type="text/css" media="all" href="qunit.css" />
-  </div>
-  <h1>Hello</h1>
-</div>
--- a/web/test/jstests/ajaxresult.json	Wed Dec 09 18:42:13 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-["foo", "bar"]
--- a/web/test/jstests/test_ajax.html	Wed Dec 09 18:42:13 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-<html>
-  <head>
-    <!-- dependencies -->
-    <script type="text/javascript">
-      var JSON_BASE_URL = '';
-    </script>
-    <script type="text/javascript" src="../../data/jquery.js"></script>
-    <script src="../../data/cubicweb.js" type="text/javascript"></script>
-    <script src="../../data/cubicweb.htmlhelpers.js" type="text/javascript"></script>
-    <script src="../../data/cubicweb.python.js" type="text/javascript"></script>
-    <script src="../../data/cubicweb.compat.js" type="text/javascript"></script>
-    <script src="../../data/cubicweb.ajax.js" type="text/javascript"></script>
-    <!-- qunit files -->
-    <script type="text/javascript" src="../../../devtools/data/qunit.js"></script>
-    <link rel="stylesheet" type="text/css" media="all" href="../../../devtools/data/qunit.css" />
-    <!-- test suite -->
-    <script src="cwmock.js" type="text/javascript"></script>
-    <script src="test_ajax.js" type="text/javascript"></script>
-  </head>
-  <body>
-    <div id="main"> </div>
-    <h1 id="qunit-header">cubicweb.ajax.js functions tests</h1>
-    <h2 id="qunit-banner"></h2>
-    <ol id="qunit-tests">
-  </body>
-</html>
--- a/web/test/jstests/test_ajax.js	Wed Dec 09 18:42:13 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,274 +0,0 @@
-$(document).ready(function() {
-
-    QUnit.module("ajax", {
-        setup: function() {
-          this.scriptsLength = $('head script[src]').length-1;
-          this.cssLength = $('head link[rel=stylesheet]').length-1;
-          // re-initialize cw loaded cache so that each tests run in a
-          // clean environment, have a lookt at _loadAjaxHtmlHead implementation
-          // in cubicweb.ajax.js for more information.
-          cw.loaded_scripts = [];
-          cw.loaded_links = [];
-        },
-        teardown: function() {
-          $('head script[src]:lt(' + ($('head script[src]').length - 1 - this.scriptsLength) + ')').remove();
-          $('head link[rel=stylesheet]:gt(' + this.cssLength + ')').remove();
-        }
-      });
-
-    function jsSources() {
-        return $.map($('head script[src]'), function(script) {
-            return script.getAttribute('src');
-        });
-    }
-
-    QUnit.test('test simple h1 inclusion (ajax_url0.html)', function (assert) {
-        assert.expect(3);
-        assert.equal($('#qunit-fixture').children().length, 0);
-        var done = assert.async();
-        $('#qunit-fixture').loadxhtml(BASE_URL + 'cwsoftwareroot/web/test/jstests/ajax_url0.html')
-        .addCallback(function() {
-                try {
-                    assert.equal($('#qunit-fixture').children().length, 1);
-                    assert.equal($('#qunit-fixture h1').html(), 'Hello');
-                } finally {
-                    done();
-                };
-            }
-        );
-    });
-
-    QUnit.test('test simple html head inclusion (ajax_url1.html)', function (assert) {
-        assert.expect(6);
-        var scriptsIncluded = jsSources();
-        assert.equal(jQuery.inArray('http://foo.js', scriptsIncluded), - 1);
-        var done = assert.async();
-        $('#qunit-fixture').loadxhtml(BASE_URL + 'cwsoftwareroot/web/test/jstests/ajax_url1.html')
-        .addCallback(function() {
-                try {
-                    var origLength = scriptsIncluded.length;
-                    scriptsIncluded = jsSources();
-                    // check that foo.js has been prepended to <head>
-                    assert.equal(scriptsIncluded.length, origLength + 1);
-                    assert.equal(scriptsIncluded.indexOf('http://foo.js'), 0);
-                    // check that <div class="ajaxHtmlHead"> has been removed
-                    assert.equal($('#qunit-fixture').children().length, 1);
-                    assert.equal($('div.ajaxHtmlHead').length, 0);
-                    assert.equal($('#qunit-fixture h1').html(), 'Hello');
-                } finally {
-                    done();
-                };
-            }
-        );
-    });
-
-    QUnit.test('test addCallback', function (assert) {
-        assert.expect(3);
-        assert.equal($('#qunit-fixture').children().length, 0);
-        var done = assert.async();
-        var d = $('#qunit-fixture').loadxhtml(BASE_URL + 'cwsoftwareroot/web/test/jstests/ajax_url0.html');
-        d.addCallback(function() {
-            try {
-                assert.equal($('#qunit-fixture').children().length, 1);
-                assert.equal($('#qunit-fixture h1').html(), 'Hello');
-            } finally {
-                done();
-            };
-        });
-    });
-
-    QUnit.test('test callback after synchronous request', function (assert) {
-        assert.expect(1);
-        var deferred = new Deferred();
-        var result = jQuery.ajax({
-            url: BASE_URL + 'cwsoftwareroot/web/test/jstests/ajax_url0.html',
-            async: false,
-            beforeSend: function(xhr) {
-                deferred._req = xhr;
-            },
-            success: function(data, status) {
-                deferred.success(data);
-            }
-        });
-        var done = assert.async();
-        deferred.addCallback(function() {
-            try {
-                // add an assertion to ensure the callback is executed
-                assert.ok(true, "callback is executed");
-            } finally {
-                done();
-            };
-        });
-    });
-
-    QUnit.test('test addCallback with parameters', function (assert) {
-        assert.expect(3);
-        assert.equal($('#qunit-fixture').children().length, 0);
-        var done = assert.async();
-        var d = $('#qunit-fixture').loadxhtml(BASE_URL + 'cwsoftwareroot/web/test/jstests/ajax_url0.html');
-        d.addCallback(function(data, req, arg1, arg2) {
-            try {
-                assert.equal(arg1, 'Hello');
-                assert.equal(arg2, 'world');
-            } finally {
-                done();
-            };
-        },
-        'Hello', 'world');
-    });
-
-    QUnit.test('test callback after synchronous request with parameters', function (assert) {
-        assert.expect(3);
-        var deferred = new Deferred();
-        deferred.addCallback(function(data, req, arg1, arg2) {
-            // add an assertion to ensure the callback is executed
-            try {
-                assert.ok(true, "callback is executed");
-                assert.equal(arg1, 'Hello');
-                assert.equal(arg2, 'world');
-            } finally {
-                done();
-            };
-        },
-        'Hello', 'world');
-        deferred.addErrback(function() {
-            // throw an exception to start errback chain
-            try {
-                throw this._error;
-            } finally {
-                done();
-            };
-        });
-        var done = assert.async();
-        var result = jQuery.ajax({
-            url: BASE_URL + 'cwsoftwareroot/web/test/jstests/ajax_url0.html',
-            async: false,
-            beforeSend: function(xhr) {
-                deferred._req = xhr;
-            },
-            success: function(data, status) {
-                deferred.success(data);
-            }
-        });
-    });
-
-  QUnit.test('test addErrback', function (assert) {
-        assert.expect(1);
-        var done = assert.async();
-        var d = $('#qunit-fixture').loadxhtml(BASE_URL + 'cwsoftwareroot/web/test/jstests/nonexistent.html');
-        d.addCallback(function() {
-            // should not be executed
-            assert.ok(false, "callback is executed");
-        });
-        d.addErrback(function() {
-            try {
-                assert.ok(true, "errback is executed");
-            } finally {
-                done();
-            };
-        });
-    });
-
-    QUnit.test('test callback execution order', function (assert) {
-        assert.expect(3);
-        var counter = 0;
-        var done = assert.async();
-        var d = $('#qunit-fixture').loadxhtml(BASE_URL + 'cwsoftwareroot/web/test/jstests/ajax_url0.html');
-        d.addCallback(function() {
-            assert.equal(++counter, 1); // should be executed first
-        });
-        d.addCallback(function() {
-            assert.equal(++counter, 2);
-        });
-        d.addCallback(function() {
-            try {
-                assert.equal(++counter, 3);
-            } finally {
-                done();
-            }
-        });
-    });
-
-    QUnit.test('test already included resources are ignored (ajax_url1.html)', function (assert) {
-        assert.expect(10);
-        var scriptsIncluded = jsSources();
-        // NOTE:
-        assert.equal(jQuery.inArray('http://foo.js', scriptsIncluded), -1);
-        assert.equal($('head link').length, 1);
-        /* use endswith because in pytest context we have an absolute path */
-        assert.ok($('head link').attr('href').endswith('/qunit.css'), 'qunit.css is loaded');
-        var done = assert.async();
-        $('#qunit-fixture').loadxhtml(BASE_URL + 'cwsoftwareroot/web/test/jstests/ajax_url1.html')
-        .addCallback(function() {
-                var origLength = scriptsIncluded.length;
-                scriptsIncluded = jsSources();
-                try {
-                    // check that foo.js has been inserted in <head>
-                    assert.equal(scriptsIncluded.length, origLength + 1);
-                    assert.equal(scriptsIncluded.indexOf('http://foo.js'), 0);
-                    // check that <div class="ajaxHtmlHead"> has been removed
-                    assert.equal($('#qunit-fixture').children().length, 1);
-                    assert.equal($('div.ajaxHtmlHead').length, 0);
-                    assert.equal($('#qunit-fixture h1').html(), 'Hello');
-                    // qunit.css is not added twice
-                    assert.equal($('head link').length, 1);
-                    /* use endswith because in pytest context we have an absolute path */
-                    assert.ok($('head link').attr('href').endswith('/qunit.css'), 'qunit.css is loaded');
-                } finally {
-                    done();
-                }
-            }
-        );
-    });
-
-    QUnit.test('test synchronous request loadRemote', function (assert) {
-        var res = loadRemote(BASE_URL + 'cwsoftwareroot/web/test/jstests/ajaxresult.json', {},
-        'GET', true);
-        assert.deepEqual(res, ['foo', 'bar']);
-    });
-
-    QUnit.test('test event on CubicWeb', function (assert) {
-        assert.expect(1);
-        var done = assert.async();
-        var events = null;
-        $(CubicWeb).bind('server-response', function() {
-            // check that server-response event on CubicWeb is triggered
-            events = 'CubicWeb';
-        });
-        $('#qunit-fixture').loadxhtml(BASE_URL + 'cwsoftwareroot/web/test/jstests/ajax_url0.html')
-        .addCallback(function() {
-                try {
-                    assert.equal(events, 'CubicWeb');
-                } finally {
-                    done();
-                };
-            }
-        );
-    });
-
-    QUnit.test('test event on node', function (assert) {
-        assert.expect(3);
-        var done = assert.async();
-        var nodes = [];
-        $('#qunit-fixture').bind('server-response', function() {
-            nodes.push('node');
-        });
-        $(CubicWeb).bind('server-response', function() {
-            nodes.push('CubicWeb');
-        });
-        $('#qunit-fixture').loadxhtml(BASE_URL + 'cwsoftwareroot/web/test/jstests/ajax_url0.html')
-        .addCallback(function() {
-                try {
-                    assert.equal(nodes.length, 2);
-                    // check that server-response event on CubicWeb is triggered
-                    // only once and event server-response on node is triggered
-                    assert.equal(nodes[0], 'CubicWeb');
-                    assert.equal(nodes[1], 'node');
-                } finally {
-                    done();
-                };
-            }
-        );
-    });
-});
-
--- a/web/test/jstests/test_htmlhelpers.html	Wed Dec 09 18:42:13 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-<html>
-  <head>
-    <!-- dependencies -->
-    <script type="text/javascript" src="../../data/jquery.js"></script>
-    <script src="../../data/cubicweb.python.js" type="text/javascript"></script>
-    <script src="../../data/cubicweb.js" type="text/javascript"></script>
-    <script src="../../data/cubicweb.compat.js" type="text/javascript"></script>
-    <script src="../../data/cubicweb.htmlhelpers.js" type="text/javascript"></script>
-    <!-- qunit files -->
-    <script type="text/javascript" src="../../../devtools/data/qunit.js"></script>
-    <link rel="stylesheet" type="text/css" media="all" href="../../../devtools/data/qunit.css" />
-    <!-- test suite -->
-    <script src="cwmock.js" type="text/javascript"></script>
-    <script src="test_htmlhelpers.js" type="text/javascript"></script>
-  </head>
-  <body>
-    <div id="main"> </div>
-    <h1 id="qunit-header">cubicweb.htmlhelpers.js functions tests</h1>
-    <h2 id="qunit-banner"></h2>
-    <ol id="qunit-tests">
-  </body>
-</html>
--- a/web/test/jstests/test_htmlhelpers.js	Wed Dec 09 18:42:13 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-$(document).ready(function() {
-
-    QUnit.module("module2", {
-      setup: function() {
-        $('#qunit-fixture').append('<select id="theselect" multiple="multiple" size="2">' +
-    			'</select>');
-      }
-    });
-
-    QUnit.test("test first selected", function (assert) {
-        $('#theselect').append('<option value="foo">foo</option>' +
-    			     '<option selected="selected" value="bar">bar</option>' +
-    			     '<option value="baz">baz</option>' +
-    			     '<option selected="selecetd"value="spam">spam</option>');
-        var selected = firstSelected(document.getElementById("theselect"));
-        assert.equal(selected.value, 'bar');
-    });
-
-    QUnit.test("test first selected 2", function (assert) {
-        $('#theselect').append('<option value="foo">foo</option>' +
-    			     '<option value="bar">bar</option>' +
-    			     '<option value="baz">baz</option>' +
-    			     '<option value="spam">spam</option>');
-        var selected = firstSelected(document.getElementById("theselect"));
-        assert.equal(selected, null);
-    });
-
-    QUnit.module("visibilty");
-    QUnit.test('toggleVisibility', function (assert) {
-        $('#qunit-fixture').append('<div id="foo"></div>');
-        toggleVisibility('foo');
-        assert.ok($('#foo').hasClass('hidden'), 'check hidden class is set');
-    });
-
-});
-
--- a/web/test/jstests/test_utils.html	Wed Dec 09 18:42:13 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-<html>
-  <head>
-    <!-- dependencies -->
-    <script type="text/javascript" src="utils.js"></script>
-    <script type="text/javascript" src="../../data/jquery.js"></script>
-    <script src="../../data/cubicweb.python.js" type="text/javascript"></script>
-    <script src="../../data/cubicweb.js" type="text/javascript"></script>
-    <script src="../../data/cubicweb.compat.js" type="text/javascript"></script>
-    <!-- qunit files -->
-    <script type="text/javascript" src="../../../devtools/data/qunit.js"></script>
-    <link rel="stylesheet" type="text/css" media="all" href="../../../devtools/data/qunit.css" />
-    <!-- test suite -->
-    <script src="cwmock.js" type="text/javascript"></script>
-    <script src="test_utils.js" type="text/javascript"></script>
-  </head>
-  <body>
-    <div id="main"> </div>
-    <h1 id="qunit-header">cw.utils functions tests</h1>
-    <h2 id="qunit-banner"></h2>
-    <ol id="qunit-tests">
-  </body>
-</html>
--- a/web/test/jstests/test_utils.js	Wed Dec 09 18:42:13 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-$(document).ready(function() {
-
-  QUnit.module("datetime");
-
-  QUnit.test("test full datetime", function (assert) {
-      assert.equal(cw.utils.toISOTimestamp(new Date(1986, 3, 18, 10, 30, 0, 0)),
-	     '1986-04-18 10:30:00');
-  });
-
-  QUnit.test("test only date", function (assert) {
-      assert.equal(cw.utils.toISOTimestamp(new Date(1986, 3, 18)), '1986-04-18 00:00:00');
-  });
-
-  QUnit.test("test null", function (assert) {
-      assert.equal(cw.utils.toISOTimestamp(null), null);
-  });
-
-  QUnit.module("parsing");
-  QUnit.test("test basic number parsing", function (assert) {
-      var d = strptime('2008/08/08', '%Y/%m/%d');
-      assert.deepEqual(datetuple(d), [2008, 8, 8, 0, 0]);
-      d = strptime('2008/8/8', '%Y/%m/%d');
-      assert.deepEqual(datetuple(d), [2008, 8, 8, 0, 0]);
-      d = strptime('8/8/8', '%Y/%m/%d');
-      assert.deepEqual(datetuple(d), [8, 8, 8, 0, 0]);
-      d = strptime('0/8/8', '%Y/%m/%d');
-      assert.deepEqual(datetuple(d), [0, 8, 8, 0, 0]);
-      d = strptime('-10/8/8', '%Y/%m/%d');
-      assert.deepEqual(datetuple(d), [-10, 8, 8, 0, 0]);
-      d = strptime('-35000', '%Y');
-      assert.deepEqual(datetuple(d), [-35000, 1, 1, 0, 0]);
-  });
-
-  QUnit.test("test custom format parsing", function (assert) {
-      var d = strptime('2008-08-08', '%Y-%m-%d');
-      assert.deepEqual(datetuple(d), [2008, 8, 8, 0, 0]);
-      d = strptime('2008 - !  08: 08', '%Y - !  %m: %d');
-      assert.deepEqual(datetuple(d), [2008, 8, 8, 0, 0]);
-      d = strptime('2008-08-08 12:14', '%Y-%m-%d %H:%M');
-      assert.deepEqual(datetuple(d), [2008, 8, 8, 12, 14]);
-      d = strptime('2008-08-08 1:14', '%Y-%m-%d %H:%M');
-      assert.deepEqual(datetuple(d), [2008, 8, 8, 1, 14]);
-      d = strptime('2008-08-08 01:14', '%Y-%m-%d %H:%M');
-      assert.deepEqual(datetuple(d), [2008, 8, 8, 1, 14]);
-  });
-
-  QUnit.module("sliceList");
-  QUnit.test("test slicelist", function (assert) {
-      var list = ['a', 'b', 'c', 'd', 'e', 'f'];
-      assert.deepEqual(cw.utils.sliceList(list, 2),  ['c', 'd', 'e', 'f']);
-      assert.deepEqual(cw.utils.sliceList(list, 2, -2), ['c', 'd']);
-      assert.deepEqual(cw.utils.sliceList(list, -3), ['d', 'e', 'f']);
-      assert.deepEqual(cw.utils.sliceList(list, 0, -2), ['a', 'b', 'c', 'd']);
-      assert.deepEqual(cw.utils.sliceList(list),  list);
-  });
-
-  QUnit.module("formContents", {
-    setup: function() {
-      $('#qunit-fixture').append('<form id="test-form"></form>');
-    }
-  });
-  // XXX test fckeditor
-  QUnit.test("test formContents", function (assert) {
-      $('#test-form').append('<input name="input-text" ' +
-			     'type="text" value="toto" />');
-      $('#test-form').append('<textarea rows="10" cols="30" '+
-			     'name="mytextarea">Hello World!</textarea> ');
-      $('#test-form').append('<input name="choice" type="radio" ' +
-			     'value="yes" />');
-      $('#test-form').append('<input name="choice" type="radio" ' +
-			     'value="no" checked="checked"/>');
-      $('#test-form').append('<input name="check" type="checkbox" ' +
-			     'value="yes" />');
-      $('#test-form').append('<input name="check" type="checkbox" ' +
-			     'value="no" checked="checked"/>');
-      $('#test-form').append('<select id="theselect" name="theselect" ' +
-			     'multiple="multiple" size="2"></select>');
-      $('#theselect').append('<option selected="selected" ' +
-			     'value="foo">foo</option>' +
-  			     '<option value="bar">bar</option>');
-      //Append an unchecked radio input : should not be in formContents list
-      $('#test-form').append('<input name="unchecked-choice" type="radio" ' +
-			     'value="one" />');
-      $('#test-form').append('<input name="unchecked-choice" type="radio" ' +
-			     'value="two"/>');
-      assert.deepEqual(cw.utils.formContents($('#test-form')[0]), [
-	['input-text', 'mytextarea', 'choice', 'check', 'theselect'],
-	['toto', 'Hello World!', 'no', 'no', 'foo']
-      ]);
-  });
-});
-
--- a/web/test/jstests/utils.js	Wed Dec 09 18:42:13 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-function datetuple(d) {
-    return [d.getFullYear(), d.getMonth()+1, d.getDate(),
-	    d.getHours(), d.getMinutes()];
-}
-
-function pprint(obj) {
-    print('{');
-    for(k in obj) {
-	print('  ' + k + ' = ' + obj[k]);
-    }
-    print('}');
-}
-
-function arrayrepr(array) {
-    return '[' + array.join(', ') + ']';
-}
-
-function assertArrayEquals(array1, array2) {
-    if (array1.length != array2.length) {
-	throw new crosscheck.AssertionFailure(array1.join(', ') + ' != ' + array2.join(', '));
-    }
-    for (var i=0; i<array1.length; i++) {
-	if (array1[i] != array2[i]) {
-
-	    throw new crosscheck.AssertionFailure(arrayrepr(array1) + ' and ' + arrayrepr(array2)
-						 + ' differs at index ' + i);
-	}
-    }
-}
--- a/web/test/test_jscript.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/test/test_jscript.py	Thu Dec 10 12:34:15 2015 +0100
@@ -1,42 +1,38 @@
-from cubicweb.devtools.qunit import QUnitTestCase, unittest_main
+from cubicweb.devtools import qunit
 
 from os import path as osp
 
 
-class JScript(QUnitTestCase):
+class JScript(qunit.QUnitTestCase):
 
     all_js_tests = (
-        ("jstests/test_utils.js", (
-            "../../web/data/cubicweb.js",
-            "../../web/data/cubicweb.compat.js",
-            "../../web/data/cubicweb.python.js",
-            "jstests/utils.js",
+        ("/static/jstests/test_utils.js", (
+            "/data/cubicweb.js",
+            "/data/cubicweb.compat.js",
+            "/data/cubicweb.python.js",
+            "/static/jstests/utils.js",
             ),
          ),
 
-        ("jstests/test_htmlhelpers.js", (
-            "../../web/data/cubicweb.js",
-            "../../web/data/cubicweb.compat.js",
-            "../../web/data/cubicweb.python.js",
-            "../../web/data/cubicweb.htmlhelpers.js",
+        ("/static/jstests/test_htmlhelpers.js", (
+            "/data/cubicweb.js",
+            "/data/cubicweb.compat.js",
+            "/data/cubicweb.python.js",
+            "/data/cubicweb.htmlhelpers.js",
             ),
          ),
 
-        ("jstests/test_ajax.js", (
-            "../../web/data/cubicweb.python.js",
-            "../../web/data/cubicweb.js",
-            "../../web/data/cubicweb.compat.js",
-            "../../web/data/cubicweb.htmlhelpers.js",
-            "../../web/data/cubicweb.ajax.js",
-            ), (
-            "jstests/ajax_url0.html",
-            "jstests/ajax_url1.html",
-            "jstests/ajax_url2.html",
-            "jstests/ajaxresult.json",
+        ("/static/jstests/test_ajax.js", (
+            "/data/cubicweb.python.js",
+            "/data/cubicweb.js",
+            "/data/cubicweb.compat.js",
+            "/data/cubicweb.htmlhelpers.js",
+            "/data/cubicweb.ajax.js",
             ),
          ),
     )
 
 
 if __name__ == '__main__':
-    unittest_main()
+    from unittest import main
+    main()
--- a/web/test/test_views.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/test/test_views.py	Thu Dec 10 12:34:15 2015 +0100
@@ -50,19 +50,19 @@
         composite entity
         """
         with self.admin_access.web_request() as req:
-            rset = req.execute('CWUser X WHERE X login "admin"')
+            rset = req.execute(u'CWUser X WHERE X login "admin"')
             self.view('copy', rset, req=req)
 
     def test_sortable_js_added(self):
         with self.admin_access.web_request() as req:
             # sortable.js should not be included by default
             rset = req.execute('CWUser X')
-            self.assertNotIn('jquery.tablesorter.js', self.view('oneline', rset, req=req).source)
+            self.assertNotIn(b'jquery.tablesorter.js', self.view('oneline', rset, req=req).source)
 
         with self.admin_access.web_request() as req:
             # but should be included by the tableview
             rset = req.execute('Any P,F,S LIMIT 1 WHERE P is CWUser, P firstname F, P surname S')
-            self.assertIn('jquery.tablesorter.js', self.view('table', rset, req=req).source)
+            self.assertIn(b'jquery.tablesorter.js', self.view('table', rset, req=req).source)
 
     def test_js_added_only_once(self):
         with self.admin_access.web_request() as req:
@@ -70,14 +70,14 @@
             self.vreg.register(SomeView)
             rset = req.execute('CWUser X')
             source = self.view('someview', rset, req=req).source
-            self.assertEqual(source.count('spam.js'), 1)
+            self.assertEqual(source.count(b'spam.js'), 1)
 
     def test_unrelateddivs(self):
         with self.admin_access.client_cnx() as cnx:
             group = cnx.create_entity('CWGroup', name=u'R&D')
             cnx.commit()
         with self.admin_access.web_request(relation='in_group_subject') as req:
-            rset = req.execute('Any X WHERE X is CWUser, X login "admin"')
+            rset = req.execute(u'Any X WHERE X is CWUser, X login "admin"')
             self.view('unrelateddivs', rset, req=req)
 
 
--- a/web/test/unittest_application.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/test/unittest_application.py	Thu Dec 10 12:34:15 2015 +0100
@@ -17,8 +17,11 @@
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """unit tests for cubicweb.web.application"""
 
-import base64, Cookie
-import httplib
+import base64
+
+from six import text_type
+from six.moves import http_client
+from six.moves.http_cookies import SimpleCookie
 
 from logilab.common.testlib import TestCase, unittest_main
 from logilab.common.decorators import clear_cache, classproperty
@@ -179,8 +182,8 @@
 
     def test_publish_validation_error(self):
         with self.admin_access.web_request() as req:
-            user = self.user(req)
-            eid = unicode(user.eid)
+            user = req.user
+            eid = text_type(user.eid)
             req.form = {
                 'eid':       eid,
                 '__type:'+eid:    'CWUser', '_cw_entity_fields:'+eid: 'login-subject',
@@ -267,14 +270,14 @@
                 with self.admin_access.web_request(vid='test.ajax.error') as req:
                     req.ajax_request = True
                     page = app.handle_request(req, '')
-        self.assertEqual(httplib.INTERNAL_SERVER_ERROR,
+        self.assertEqual(http_client.INTERNAL_SERVER_ERROR,
                          req.status_out)
 
     def _test_cleaned(self, kwargs, injected, cleaned):
         with self.admin_access.web_request(**kwargs) as req:
             page = self.app_handle_request(req, 'view')
-            self.assertNotIn(injected, page)
-            self.assertIn(cleaned, page)
+            self.assertNotIn(injected.encode('ascii'), page)
+            self.assertIn(cleaned.encode('ascii'), page)
 
     def test_nonregr_script_kiddies(self):
         """test against current script injection"""
@@ -314,8 +317,8 @@
         self.app.handle_request(req, 'login')
         self.assertEqual(401, req.status_out)
         clear_cache(req, 'get_authorization')
-        authstr = base64.encodestring('%s:%s' % (self.admlogin, self.admpassword))
-        req.set_request_header('Authorization', 'basic %s' % authstr)
+        authstr = base64.encodestring(('%s:%s' % (self.admlogin, self.admpassword)).encode('ascii'))
+        req.set_request_header('Authorization', 'basic %s' % authstr.decode('ascii'))
         self.assertAuthSuccess(req, origsession)
         self.assertRaises(LogOut, self.app_handle_request, req, 'logout')
         self.assertEqual(len(self.open_sessions), 0)
@@ -328,8 +331,8 @@
         except Redirect as redir:
             self.fail('anonymous user should get login form')
         clear_cache(req, 'get_authorization')
-        self.assertIn('__login', form)
-        self.assertIn('__password', form)
+        self.assertIn(b'__login', form)
+        self.assertIn(b'__password', form)
         self.assertFalse(req.cnx) # Mock cnx are False
         req.form['__login'] = self.admlogin
         req.form['__password'] = self.admpassword
@@ -361,7 +364,7 @@
     def _reset_cookie(self, req):
         # preparing the suite of the test
         # set session id in cookie
-        cookie = Cookie.SimpleCookie()
+        cookie = SimpleCookie()
         sessioncookie = self.app.session_handler.session_cookie(req)
         cookie[sessioncookie] = req.session.sessionid
         req.set_request_header('Cookie', cookie[sessioncookie].OutputString(),
@@ -390,11 +393,11 @@
     def test_http_auth_anon_allowed(self):
         req, origsession = self.init_authentication('http', 'anon')
         self._test_auth_anon(req)
-        authstr = base64.encodestring('toto:pouet')
-        req.set_request_header('Authorization', 'basic %s' % authstr)
+        authstr = base64.encodestring(b'toto:pouet')
+        req.set_request_header('Authorization', 'basic %s' % authstr.decode('ascii'))
         self._test_anon_auth_fail(req)
-        authstr = base64.encodestring('%s:%s' % (self.admlogin, self.admpassword))
-        req.set_request_header('Authorization', 'basic %s' % authstr)
+        authstr = base64.encodestring(('%s:%s' % (self.admlogin, self.admpassword)).encode('ascii'))
+        req.set_request_header('Authorization', 'basic %s' % authstr.decode('ascii'))
         self.assertAuthSuccess(req, origsession)
         self.assertRaises(LogOut, self.app_handle_request, req, 'logout')
         self.assertEqual(len(self.open_sessions), 0)
--- a/web/test/unittest_facet.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/test/unittest_facet.py	Thu Dec 10 12:34:15 2015 +0100
@@ -70,8 +70,8 @@
 
     def test_relation_optional_rel(self):
         with self.admin_access.web_request() as req:
-            rset = req.cnx.execute('Any X,GROUP_CONCAT(GN) GROUPBY X '
-                                   'WHERE X in_group G?, G name GN, NOT G name "users"')
+            rset = req.cnx.execute(u'Any X,GROUP_CONCAT(GN) GROUPBY X '
+                                    'WHERE X in_group G?, G name GN, NOT G name "users"')
             rqlst = rset.syntax_tree().copy()
             select = rqlst.children[0]
             filtered_variable, baserql = facet.init_facets(rset, select)
@@ -87,18 +87,18 @@
             self.assertEqual(f.vocabulary(),
                              [(u'guests', guests), (u'managers', managers)])
             # ensure rqlst is left unmodified
-            self.assertEqual(rqlst.as_string(), "DISTINCT Any  WHERE X in_group G?, G name GN, NOT G name 'users'")
+            self.assertEqual(rqlst.as_string(), 'DISTINCT Any  WHERE X in_group G?, G name GN, NOT G name "users"')
             #rqlst = rset.syntax_tree()
             self.assertEqual(sorted(f.possible_values()),
                              [str(guests), str(managers)])
             # ensure rqlst is left unmodified
-            self.assertEqual(rqlst.as_string(), "DISTINCT Any  WHERE X in_group G?, G name GN, NOT G name 'users'")
+            self.assertEqual(rqlst.as_string(), 'DISTINCT Any  WHERE X in_group G?, G name GN, NOT G name "users"')
             req.form[f.__regid__] = str(guests)
             f.add_rql_restrictions()
             # selection is cluttered because rqlst has been prepared for facet (it
             # is not in real life)
             self.assertEqual(f.select.as_string(),
-                             "DISTINCT Any  WHERE X in_group G?, G name GN, NOT G name 'users', X in_group D, D eid %s" % guests)
+                             'DISTINCT Any  WHERE X in_group G?, G name GN, NOT G name "users", X in_group D, D eid %s' % guests)
 
     def test_relation_no_relation_1(self):
         with self.admin_access.web_request() as req:
@@ -141,12 +141,12 @@
                               ['guests', 'managers'])
             # ensure rqlst is left unmodified
             self.assertEqual(f.select.as_string(), 'DISTINCT Any  WHERE X is CWUser')
-            f._cw.form[f.__regid__] = 'guests'
+            f._cw.form[f.__regid__] = u'guests'
             f.add_rql_restrictions()
             # selection is cluttered because rqlst has been prepared for facet (it
             # is not in real life)
             self.assertEqual(f.select.as_string(),
-                              "DISTINCT Any  WHERE X is CWUser, X in_group E, E name 'guests'")
+                             'DISTINCT Any  WHERE X is CWUser, X in_group E, E name "guests"')
 
     def test_hasrelation(self):
         with self.admin_access.web_request() as req:
@@ -207,12 +207,12 @@
                               ['admin', 'anon'])
             # ensure rqlst is left unmodified
             self.assertEqual(rqlst.as_string(), 'DISTINCT Any  WHERE X is CWUser')
-            req.form[f.__regid__] = 'admin'
+            req.form[f.__regid__] = u'admin'
             f.add_rql_restrictions()
             # selection is cluttered because rqlst has been prepared for facet (it
             # is not in real life)
             self.assertEqual(f.select.as_string(),
-                              "DISTINCT Any  WHERE X is CWUser, X login 'admin'")
+                             'DISTINCT Any  WHERE X is CWUser, X login "admin"')
 
     def test_bitfield(self):
         with self.admin_access.web_request() as req:
@@ -310,12 +310,12 @@
             self.assertEqual(f.possible_values(), ['admin',])
             # ensure rqlst is left unmodified
             self.assertEqual(rqlst.as_string(), 'DISTINCT Any  WHERE X is CWUser')
-            req.form[f.__regid__] = 'admin'
+            req.form[f.__regid__] = u'admin'
             f.add_rql_restrictions()
             # selection is cluttered because rqlst has been prepared for facet (it
             # is not in real life)
             self.assertEqual(f.select.as_string(),
-                             "DISTINCT Any  WHERE X is CWUser, X created_by G, G owned_by H, H login 'admin'")
+                             'DISTINCT Any  WHERE X is CWUser, X created_by G, G owned_by H, H login "admin"')
 
     def test_rql_path_check_filter_label_variable(self):
         with self.admin_access.web_request() as req:
@@ -359,13 +359,13 @@
 
     def prepareg_aggregat_rqlst(self, req):
         return self.prepare_rqlst(req,
-            'Any 1, COUNT(X) WHERE X is CWUser, X creation_date XD, '
-            'X modification_date XM, Y creation_date YD, Y is CWGroup '
-            'HAVING DAY(XD)>=DAY(YD) AND DAY(XM)<=DAY(YD)', 'X',
-            expected_baserql='Any 1,COUNT(X) WHERE X is CWUser, X creation_date XD, '
+            u'Any 1, COUNT(X) WHERE X is CWUser, X creation_date XD, '
+             'X modification_date XM, Y creation_date YD, Y is CWGroup '
+             'HAVING DAY(XD)>=DAY(YD) AND DAY(XM)<=DAY(YD)', 'X',
+            expected_baserql=u'Any 1,COUNT(X) WHERE X is CWUser, X creation_date XD, '
             'X modification_date XM, Y creation_date YD, Y is CWGroup '
             'HAVING DAY(XD) >= DAY(YD), DAY(XM) <= DAY(YD)',
-            expected_preparedrql='DISTINCT Any  WHERE X is CWUser, X creation_date XD, '
+            expected_preparedrql=u'DISTINCT Any  WHERE X is CWUser, X creation_date XD, '
             'X modification_date XM, Y creation_date YD, Y is CWGroup '
             'HAVING DAY(XD) >= DAY(YD), DAY(XM) <= DAY(YD)')
 
@@ -390,13 +390,13 @@
                     filtered_variable=filtered_variable)
             self.assertEqual(f.vocabulary(), [(u'admin', u'admin')])
             self.assertEqual(f.possible_values(), ['admin'])
-            req.form[f.__regid__] = 'admin'
+            req.form[f.__regid__] = u'admin'
             f.add_rql_restrictions()
             self.assertEqual(f.select.as_string(),
-                             "DISTINCT Any  WHERE X is CWUser, X creation_date XD, "
-                             "X modification_date XM, Y creation_date YD, Y is CWGroup, "
-                             "X created_by G, G owned_by H, H login 'admin' "
-                             "HAVING DAY(XD) >= DAY(YD), DAY(XM) <= DAY(YD)")
+                             'DISTINCT Any  WHERE X is CWUser, X creation_date XD, '
+                             'X modification_date XM, Y creation_date YD, Y is CWGroup, '
+                             'X created_by G, G owned_by H, H login "admin" '
+                             'HAVING DAY(XD) >= DAY(YD), DAY(XM) <= DAY(YD)')
 
     def test_aggregat_query_attribute(self):
         with self.admin_access.web_request() as req:
@@ -409,12 +409,12 @@
                               [(u'admin', u'admin'), (u'anon', u'anon')])
             self.assertEqual(f.possible_values(),
                               ['admin', 'anon'])
-            req.form[f.__regid__] = 'admin'
+            req.form[f.__regid__] = u'admin'
             f.add_rql_restrictions()
             self.assertEqual(f.select.as_string(),
-                              "DISTINCT Any  WHERE X is CWUser, X creation_date XD, "
-                              "X modification_date XM, Y creation_date YD, Y is CWGroup, X login 'admin' "
-                              "HAVING DAY(XD) >= DAY(YD), DAY(XM) <= DAY(YD)")
+                             'DISTINCT Any  WHERE X is CWUser, X creation_date XD, '
+                             'X modification_date XM, Y creation_date YD, Y is CWGroup, X login "admin" '
+                             'HAVING DAY(XD) >= DAY(YD), DAY(XM) <= DAY(YD)')
 
 if __name__ == '__main__':
     from logilab.common.testlib import unittest_main
--- a/web/test/unittest_form.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/test/unittest_form.py	Thu Dec 10 12:34:15 2015 +0100
@@ -21,6 +21,8 @@
 from xml.etree.ElementTree import fromstring
 from lxml import html
 
+from six import text_type
+
 from logilab.common.testlib import unittest_main
 
 from cubicweb import Binary, ValidationError
@@ -65,19 +67,19 @@
             t = req.create_entity('Tag', name=u'x')
             form1 = self.vreg['forms'].select('edition', req, entity=t)
             choices = [reid for rview, reid in form1.field_by_name('tags', 'subject', t.e_schema).choices(form1)]
-            self.assertIn(unicode(b.eid), choices)
+            self.assertIn(text_type(b.eid), choices)
             form2 = self.vreg['forms'].select('edition', req, entity=b)
             choices = [reid for rview, reid in form2.field_by_name('tags', 'object', t.e_schema).choices(form2)]
-            self.assertIn(unicode(t.eid), choices)
+            self.assertIn(text_type(t.eid), choices)
 
             b.cw_clear_all_caches()
             t.cw_clear_all_caches()
             req.cnx.execute('SET X tags Y WHERE X is Tag, Y is BlogEntry')
 
             choices = [reid for rview, reid in form1.field_by_name('tags', 'subject', t.e_schema).choices(form1)]
-            self.assertIn(unicode(b.eid), choices)
+            self.assertIn(text_type(b.eid), choices)
             choices = [reid for rview, reid in form2.field_by_name('tags', 'object', t.e_schema).choices(form2)]
-            self.assertIn(unicode(t.eid), choices)
+            self.assertIn(text_type(t.eid), choices)
 
     def test_form_field_choices_new_entity(self):
         with self.admin_access.web_request() as req:
@@ -217,7 +219,7 @@
                 eidparam=True, role='subject')
         with self.admin_access.web_request() as req:
             file = req.create_entity('File', data_name=u"pouet.txt", data_encoding=u'UTF-8',
-                                     data=Binary('new widgets system'))
+                                     data=Binary(b'new widgets system'))
             form = FFForm(req, redirect_path='perdu.com', entity=file)
             self.assertMultiLineEqual(self._render_entity_field(req, 'data', form),
                               '''<input id="data-subject:%(eid)s" name="data-subject:%(eid)s" tabindex="1" type="file" value="" />
@@ -241,7 +243,7 @@
                 eidparam=True, role='subject')
         with self.admin_access.web_request() as req:
             file = req.create_entity('File', data_name=u"pouet.txt", data_encoding=u'UTF-8',
-                                     data=Binary('new widgets system'))
+                                     data=Binary(b'new widgets system'))
             form = EFFForm(req, redirect_path='perdu.com', entity=file)
             self.assertMultiLineEqual(self._render_entity_field(req, 'data', form),
                               '''<input id="data-subject:%(eid)s" name="data-subject:%(eid)s" tabindex="1" type="file" value="" />
--- a/web/test/unittest_formfields.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/test/unittest_formfields.py	Thu Dec 10 12:34:15 2015 +0100
@@ -21,6 +21,7 @@
 
 from yams.constraints import StaticVocabularyConstraint, SizeConstraint
 
+import cubicweb
 from cubicweb.devtools import TestServerConfiguration
 from cubicweb.devtools.testlib import CubicWebTC
 from cubicweb.web.formwidgets import PasswordInput, TextArea, Select, Radio
@@ -127,7 +128,7 @@
             self.assertIsInstance(field, BooleanField)
             self.assertEqual(field.required, False)
             self.assertIsInstance(field.widget, Radio)
-            self.assertEqual(field.vocabulary(mock(_cw=mock(_=unicode))),
+            self.assertEqual(field.vocabulary(mock(_cw=mock(_=cubicweb._))),
                               [(u'yes', '1'), (u'no', '')])
 
     def test_bool_field_explicit_choices(self):
@@ -135,7 +136,7 @@
             field = guess_field(schema['CWAttribute'], schema['indexed'],
                                 choices=[(u'maybe', '1'), (u'no', '')], req=req)
             self.assertIsInstance(field.widget, Radio)
-            self.assertEqual(field.vocabulary(mock(req=mock(_=unicode))),
+            self.assertEqual(field.vocabulary(mock(req=mock(_=cubicweb._))),
                               [(u'maybe', '1'), (u'no', '')])
 
 
--- a/web/test/unittest_formwidgets.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/test/unittest_formwidgets.py	Thu Dec 10 12:34:15 2015 +0100
@@ -17,23 +17,18 @@
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """unittests for cw.web.formwidgets"""
 
-from logilab.common.testlib import TestCase, unittest_main, mock_object as mock
-
-from cubicweb.devtools import TestServerConfiguration, fake
-from cubicweb.web import formwidgets, formfields
-
-from cubes.file.entities import File
+from logilab.common.testlib import unittest_main, mock_object as mock
 
-def setUpModule(*args):
-    global schema
-    config = TestServerConfiguration('data', apphome=WidgetsTC.datadir)
-    config.bootstrap_cubes()
-    schema = config.load_schema()
+from cubicweb.devtools import fake
+from cubicweb.devtools.testlib import CubicWebTC
+from cubicweb.web import formwidgets, formfields
+from cubicweb.web.views.forms import FieldsForm
 
-class WidgetsTC(TestCase):
+
+class WidgetsTC(CubicWebTC):
 
     def test_editableurl_widget(self):
-        field = formfields.guess_field(schema['Bookmark'], schema['path'])
+        field = formfields.guess_field(self.schema['Bookmark'], self.schema['path'])
         widget = formwidgets.EditableURLWidget()
         req = fake.FakeRequest(form={'path-subjectfqs:A': 'param=value&vid=view'})
         form = mock(_cw=req, formvalues={}, edited_entity=mock(eid='A'))
@@ -41,7 +36,7 @@
                          '?param=value%26vid%3Dview')
 
     def test_bitselect_widget(self):
-        field = formfields.guess_field(schema['CWAttribute'], schema['ordernum'])
+        field = formfields.guess_field(self.schema['CWAttribute'], self.schema['ordernum'])
         field.choices = [('un', '1',), ('deux', '2',)]
         widget = formwidgets.BitSelect(settabindex=False)
         req = fake.FakeRequest(form={'ordernum-subject:A': ['1', '2']})
@@ -56,5 +51,21 @@
         self.assertEqual(widget.process_field_data(form, field),
                          3)
 
+    def test_xml_escape_checkbox(self):
+        class TestForm(FieldsForm):
+            bool = formfields.BooleanField(ignore_req_params=True,
+                choices=[('python >> others', '1')],
+                widget=formwidgets.CheckBox())
+        with self.admin_access.web_request() as req:
+            form = TestForm(req, None)
+            form.build_context()
+            field = form.field_by_name('bool')
+            widget = field.widget
+            self.assertMultiLineEqual(widget._render(form, field, None),
+                '<label><input id="bool" name="bool" tabindex="1" '
+                'type="checkbox" value="1" />&#160;'
+                'python &gt;&gt; others</label>')
+
+
 if __name__ == '__main__':
     unittest_main()
--- a/web/test/unittest_http.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/test/unittest_http.py	Thu Dec 10 12:34:15 2015 +0100
@@ -253,46 +253,6 @@
         req = _test_cache(hin, hout, method='POST')
         self.assertCache(412, req.status_out, 'not modifier HEAD verb')
 
-    @tag('expires')
-    def test_expires_added(self):
-        #: Check that Expires header is added:
-        #: - when the page is modified
-        #: - when none was already present
-        hin  = [('if-none-match', 'babar'),
-               ]
-        hout = [('etag', 'rhino/really-not-babar'),
-               ]
-        req = _test_cache(hin, hout)
-        self.assertCache(None, req.status_out, 'modifier HEAD verb')
-        value = req.headers_out.getHeader('expires')
-        self.assertIsNotNone(value)
-
-    @tag('expires')
-    def test_expires_not_added(self):
-        #: Check that Expires header is not added if NOT-MODIFIED
-        hin  = [('if-none-match', 'babar'),
-               ]
-        hout = [('etag', 'babar'),
-               ]
-        req = _test_cache(hin, hout)
-        self.assertCache(304, req.status_out, 'not modifier HEAD verb')
-        value = req.headers_out.getHeader('expires')
-        self.assertIsNone(value)
-
-    @tag('expires')
-    def test_expires_no_overwrite(self):
-        #: Check that cache does not overwrite existing Expires header
-        hin  = [('if-none-match', 'babar'),
-               ]
-        DATE = 'Sat, 13 Apr 2012 14:39:32 GM'
-        hout = [('etag', 'rhino/really-not-babar'),
-                ('expires', DATE),
-               ]
-        req = _test_cache(hin, hout)
-        self.assertCache(None, req.status_out, 'not modifier HEAD verb')
-        value = req.headers_out.getRawHeaders('expires')
-        self.assertEqual(value, [DATE])
-
 
 alloworig = 'access-control-allow-origin'
 allowmethods = 'access-control-allow-methods'
--- a/web/test/unittest_idownloadable.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/test/unittest_idownloadable.py	Thu Dec 10 12:34:15 2015 +0100
@@ -42,7 +42,7 @@
         return  self.entity.name() + '.txt'
 
     def download_data(self):
-        return 'Babar is not dead!'
+        return b'Babar is not dead!'
 
 
 class BrokenIDownloadableGroup(IDownloadableUser):
@@ -72,7 +72,7 @@
                              get('content-disposition'))
             self.assertEqual(['text/plain;charset=ascii'],
                              get('content-type'))
-            self.assertEqual('Babar is not dead!', data)
+            self.assertEqual(b'Babar is not dead!', data)
 
     def test_header_with_space(self):
         with self.admin_access.web_request() as req:
@@ -87,13 +87,13 @@
                              get('content-disposition'))
             self.assertEqual(['text/plain;charset=ascii'],
                              get('content-type'))
-            self.assertEqual('Babar is not dead!', data)
+            self.assertEqual(b'Babar is not dead!', data)
 
     def test_header_with_space_and_comma(self):
         with self.admin_access.web_request() as req:
-            self.create_user(req, login=ur'c " l\ a', password='babar')
+            self.create_user(req, login=u'c " l\\ a', password='babar')
             req.cnx.commit()
-        with self.new_access(ur'c " l\ a').web_request() as req:
+        with self.new_access(u'c " l\\ a').web_request() as req:
             req.form['vid'] = 'download'
             req.form['eid'] = str(req.user.eid)
             data = self.ctrl_publish(req,'view')
@@ -102,7 +102,7 @@
                              get('content-disposition'))
             self.assertEqual(['text/plain;charset=ascii'],
                              get('content-type'))
-            self.assertEqual('Babar is not dead!', data)
+            self.assertEqual(b'Babar is not dead!', data)
 
     def test_header_unicode_filename(self):
         with self.admin_access.web_request() as req:
--- a/web/test/unittest_magicsearch.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/test/unittest_magicsearch.py	Thu Dec 10 12:34:15 2015 +0100
@@ -21,6 +21,8 @@
 import sys
 from contextlib import contextmanager
 
+from six.moves import range
+
 from logilab.common.testlib import TestCase, unittest_main
 
 from rql import BadRQLQuery, RQLSyntaxError
@@ -62,19 +64,19 @@
     def test_basic_translations(self):
         """tests basic translations (no ambiguities)"""
         with self.proc() as proc:
-            rql = "Any C WHERE C is Adresse, P adel C, C adresse 'Logilab'"
+            rql = u"Any C WHERE C is Adresse, P adel C, C adresse 'Logilab'"
             rql, = proc.preprocess_query(rql)
-            self.assertEqual(rql, "Any C WHERE C is EmailAddress, P use_email C, C address 'Logilab'")
+            self.assertEqual(rql, 'Any C WHERE C is EmailAddress, P use_email C, C address "Logilab"')
 
     def test_ambiguous_translations(self):
         """tests possibly ambiguous translations"""
         with self.proc() as proc:
-            rql = "Any P WHERE P adel C, C is EmailAddress, C nom 'Logilab'"
+            rql = u"Any P WHERE P adel C, C is EmailAddress, C nom 'Logilab'"
             rql, = proc.preprocess_query(rql)
-            self.assertEqual(rql, "Any P WHERE P use_email C, C is EmailAddress, C alias 'Logilab'")
-            rql = "Any P WHERE P is Utilisateur, P adel C, P nom 'Smith'"
+            self.assertEqual(rql, 'Any P WHERE P use_email C, C is EmailAddress, C alias "Logilab"')
+            rql = u"Any P WHERE P is Utilisateur, P adel C, P nom 'Smith'"
             rql, = proc.preprocess_query(rql)
-            self.assertEqual(rql, "Any P WHERE P is CWUser, P use_email C, P surname 'Smith'")
+            self.assertEqual(rql, 'Any P WHERE P is CWUser, P use_email C, P surname "Smith"')
 
 
 class QSPreProcessorTC(CubicWebTC):
@@ -330,7 +332,7 @@
         # suggestions should contain any possible value for
         # a given attribute (limited to 10)
         with self.admin_access.web_request() as req:
-            for i in xrange(15):
+            for i in range(15):
                 req.create_entity('Personne', nom=u'n%s' % i, prenom=u'p%s' % i)
             req.cnx.commit()
         self.assertListEqual(['Any X WHERE X is Personne, X nom "n0"',
--- a/web/test/unittest_propertysheet.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/test/unittest_propertysheet.py	Thu Dec 10 12:34:15 2015 +0100
@@ -49,19 +49,14 @@
                           'a {bgcolor: #FFFFFF; size: 1%;}')
         self.assertEqual(ps.process_resource(DATADIR, 'pouet.css'),
                          self.cachedir)
-        self.assertIn('pouet.css', ps._cache)
         self.assertFalse(ps.need_reload())
         os.utime(self.data('sheet1.py'), None)
-        self.assertIn('pouet.css', ps._cache)
         self.assertTrue(ps.need_reload())
-        self.assertIn('pouet.css', ps._cache)
         ps.reload()
-        self.assertNotIn('pouet.css', ps._cache)
         self.assertFalse(ps.need_reload())
         ps.process_resource(DATADIR, 'pouet.css') # put in cache
         os.utime(self.data('pouet.css'), None)
         self.assertFalse(ps.need_reload())
-        self.assertNotIn('pouet.css', ps._cache)
 
 
 if __name__ == '__main__':
--- a/web/test/unittest_urlpublisher.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/test/unittest_urlpublisher.py	Thu Dec 10 12:34:15 2015 +0100
@@ -25,7 +25,7 @@
 from cubicweb.rset import ResultSet
 from cubicweb.devtools.testlib import CubicWebTC
 from cubicweb.devtools.fake import FakeRequest
-from cubicweb.web import NotFound, Redirect
+from cubicweb.web import NotFound, Redirect, views
 from cubicweb.web.views.urlrewrite import SimpleReqRewriter
 
 
@@ -69,6 +69,7 @@
             self.assertEqual("Any X,AA,AB ORDERBY AB WHERE X is_instance_of CWEType, "
                              "X modification_date AA, X name AB",
                              rset.printable_rql())
+            self.assertEqual(req.form['vid'], 'sameetypelist')
 
     def test_rest_path_by_attr(self):
         with self.admin_access.web_request() as req:
@@ -91,10 +92,11 @@
                              'X firstname AA, X login AB, X modification_date AC, '
                              'X surname AD, X login "admin"',
                              rset.printable_rql())
+            self.assertEqual(req.form['vid'], 'primary')
 
     def test_rest_path_eid(self):
         with self.admin_access.web_request() as req:
-            ctrl, rset = self.process(req, 'cwuser/eid/%s' % self.user(req).eid)
+            ctrl, rset = self.process(req, 'cwuser/eid/%s' % req.user.eid)
             self.assertEqual(ctrl, 'view')
             self.assertEqual(len(rset), 1)
             self.assertEqual(rset.description[0][0], 'CWUser')
@@ -125,6 +127,15 @@
                              'X title "hell\'o"',
                              rset.printable_rql())
 
+    def test_rest_path_use_vid_from_rset(self):
+        with self.admin_access.web_request(headers={'Accept': 'application/rdf+xml'}) as req:
+            views.VID_BY_MIMETYPE['application/rdf+xml'] = 'rdf'
+            try:
+                ctrl, rset = self.process(req, 'CWEType')
+            finally:
+                views.VID_BY_MIMETYPE.pop('application/rdf+xml')
+            self.assertEqual(req.form['vid'], 'rdf')
+
     def test_rest_path_errors(self):
         with self.admin_access.web_request() as req:
             self.assertRaises(NotFound, self.process, req, 'CWUser/eid/30000')
@@ -141,25 +152,24 @@
             self.assertRaises(NotFound, self.process, req, '1/non_action')
             self.assertRaises(NotFound, self.process, req, 'CWUser/login/admin/non_action')
 
-
     def test_regexp_path(self):
         """tests the regexp path resolution"""
         with self.admin_access.web_request() as req:
             ctrl, rset = self.process(req, 'add/Task')
             self.assertEqual(ctrl, 'view')
             self.assertEqual(rset, None)
-            self.assertEqual(req.form, {'etype' : "Task", 'vid' : "creation"})
+            self.assertEqual(req.form, {'etype': "Task", 'vid': "creation"})
             self.assertRaises(NotFound, self.process, req, 'add/foo/bar')
 
     def test_nonascii_path(self):
         oldrules = SimpleReqRewriter.rules
-        SimpleReqRewriter.rules = [(re.compile('/\w+', re.U), dict(vid='foo')),]
+        SimpleReqRewriter.rules = [(re.compile('/\w+', re.U), dict(vid='foo'))]
         with self.admin_access.web_request() as req:
             try:
                 path = str(FakeRequest().url_quote(u'été'))
                 ctrl, rset = self.process(req, path)
                 self.assertEqual(rset, None)
-                self.assertEqual(req.form, {'vid' : "foo"})
+                self.assertEqual(req.form, {'vid': "foo"})
             finally:
                 SimpleReqRewriter.rules = oldrules
 
--- a/web/test/unittest_urlrewrite.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/test/unittest_urlrewrite.py	Thu Dec 10 12:34:15 2015 +0100
@@ -16,6 +16,8 @@
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 
+from six import text_type
+
 from logilab.common import tempattr
 
 from cubicweb.devtools.testlib import CubicWebTC
@@ -137,8 +139,8 @@
                  rgx_action(r'Any X WHERE X surname %(sn)s, '
                             'X firstname %(fn)s',
                             argsgroups=('sn', 'fn'),
-                            transforms={'sn' : unicode.capitalize,
-                                        'fn' : unicode.lower,})),
+                            transforms={'sn' : text_type.capitalize,
+                                        'fn' : text_type.lower,})),
                 ]
         with self.admin_access.web_request() as req:
             rewriter = TestSchemaBasedRewriter(req)
--- a/web/test/unittest_views_basecontrollers.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/test/unittest_views_basecontrollers.py	Thu Dec 10 12:34:15 2015 +0100
@@ -17,12 +17,8 @@
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """cubicweb.web.views.basecontrollers unit tests"""
 
-from urlparse import urlsplit, urlunsplit, urljoin
-# parse_qs is deprecated in cgi and has been moved to urlparse in Python 2.6
-try:
-    from urlparse import parse_qs as url_parse_query
-except ImportError:
-    from cgi import parse_qs as url_parse_query
+from six import text_type
+from six.moves.urllib.parse import urlsplit, urlunsplit, urljoin, parse_qs
 
 import lxml
 
@@ -82,7 +78,7 @@
                     }
             with self.assertRaises(ValidationError) as cm:
                 self.ctrl_publish(req)
-                cm.exception.translate(unicode)
+                cm.exception.translate(text_type)
                 self.assertEqual({'login-subject': 'the value "admin" is already used, use another one'},
                                  cm.exception.errors)
 
@@ -136,12 +132,12 @@
             user = req.user
             groupeids = [eid for eid, in req.execute('CWGroup G WHERE G name '
                                                      'in ("managers", "users")')]
-            groups = [unicode(eid) for eid in groupeids]
-            eid = unicode(user.eid)
+            groups = [text_type(eid) for eid in groupeids]
+            eid = text_type(user.eid)
             req.form = {
                 'eid': eid, '__type:'+eid: 'CWUser',
                 '_cw_entity_fields:'+eid: 'login-subject,firstname-subject,surname-subject,in_group-subject',
-                'login-subject:'+eid:     unicode(user.login),
+                'login-subject:'+eid:     text_type(user.login),
                 'surname-subject:'+eid: u'Th\xe9nault',
                 'firstname-subject:'+eid:   u'Sylvain',
                 'in_group-subject:'+eid:  groups,
@@ -159,7 +155,7 @@
             self.create_user(cnx, u'user')
             cnx.commit()
         with self.new_access(u'user').web_request() as req:
-            eid = unicode(req.user.eid)
+            eid = text_type(req.user.eid)
             req.form = {
                 'eid': eid, '__maineid' : eid,
                 '__type:'+eid: 'CWUser',
@@ -179,12 +175,12 @@
         with self.admin_access.web_request() as req:
             user = req.user
             groupeids = [g.eid for g in user.in_group]
-            eid = unicode(user.eid)
+            eid = text_type(user.eid)
             req.form = {
                 'eid':       eid,
                 '__type:'+eid:    'CWUser',
                 '_cw_entity_fields:'+eid: 'login-subject,firstname-subject,surname-subject',
-                'login-subject:'+eid:     unicode(user.login),
+                'login-subject:'+eid:     text_type(user.login),
                 'firstname-subject:'+eid: u'Th\xe9nault',
                 'surname-subject:'+eid:   u'Sylvain',
                 }
@@ -207,7 +203,7 @@
                         'login-subject:X': u'adim',
                         'upassword-subject:X': u'toto', 'upassword-subject-confirm:X': u'toto',
                         'surname-subject:X': u'Di Mascio',
-                        'in_group-subject:X': unicode(gueid),
+                        'in_group-subject:X': text_type(gueid),
 
                         '__type:Y': 'EmailAddress',
                         '_cw_entity_fields:Y': 'address-subject,use_email-object',
@@ -231,7 +227,7 @@
 
                         '__type:Y': 'File',
                         '_cw_entity_fields:Y': 'data-subject,described_by_test-object',
-                        'data-subject:Y': (u'coucou.txt', Binary('coucou')),
+                        'data-subject:Y': (u'coucou.txt', Binary(b'coucou')),
                         'described_by_test-object:Y': 'X',
                         }
             path, _params = self.expect_redirect_handle_request(req, 'edit')
@@ -256,7 +252,7 @@
 
                         '__type:Y': 'File',
                         '_cw_entity_fields:Y': 'data-subject',
-                        'data-subject:Y': (u'coucou.txt', Binary('coucou')),
+                        'data-subject:Y': (u'coucou.txt', Binary(b'coucou')),
                         }
             path, _params = self.expect_redirect_handle_request(req, 'edit')
             self.assertTrue(path.startswith('salesterm/'), path)
@@ -274,7 +270,7 @@
         # non regression test for #3120495. Without the fix, leads to
         # "unhashable type: 'list'" error
         with self.admin_access.web_request() as req:
-            cwrelation = unicode(req.execute('CWEType X WHERE X name "CWSource"')[0][0])
+            cwrelation = text_type(req.execute('CWEType X WHERE X name "CWSource"')[0][0])
             req.form = {'eid': [cwrelation], '__maineid' : cwrelation,
 
                         '__type:'+cwrelation: 'CWEType',
@@ -287,7 +283,7 @@
 
     def test_edit_multiple_linked(self):
         with self.admin_access.web_request() as req:
-            peid = unicode(self.create_user(req, u'adim').eid)
+            peid = text_type(self.create_user(req, u'adim').eid)
             req.form = {'eid': [peid, 'Y'], '__maineid': peid,
 
                         '__type:'+peid: u'CWUser',
@@ -307,7 +303,7 @@
             self.assertEqual(email.address, 'dima@logilab.fr')
 
         # with self.admin_access.web_request() as req:
-            emaileid = unicode(email.eid)
+            emaileid = text_type(email.eid)
             req.form = {'eid': [peid, emaileid],
 
                         '__type:'+peid: u'CWUser',
@@ -329,7 +325,7 @@
         with self.admin_access.web_request() as req:
             user = req.user
             req.form = {'eid': 'X',
-                        '__cloned_eid:X': unicode(user.eid), '__type:X': 'CWUser',
+                        '__cloned_eid:X': text_type(user.eid), '__type:X': 'CWUser',
                         '_cw_entity_fields:X': 'login-subject,upassword-subject',
                         'login-subject:X': u'toto',
                         'upassword-subject:X': u'toto',
@@ -338,7 +334,7 @@
                 self.ctrl_publish(req)
             self.assertEqual({'upassword-subject': u'password and confirmation don\'t match'},
                              cm.exception.errors)
-            req.form = {'__cloned_eid:X': unicode(user.eid),
+            req.form = {'__cloned_eid:X': text_type(user.eid),
                         'eid': 'X', '__type:X': 'CWUser',
                         '_cw_entity_fields:X': 'login-subject,upassword-subject',
                         'login-subject:X': u'toto',
@@ -354,7 +350,7 @@
     def test_interval_bound_constraint_success(self):
         with self.admin_access.repo_cnx() as cnx:
             feid = cnx.execute('INSERT File X: X data_name "toto.txt", X data %(data)s',
-                               {'data': Binary('yo')})[0][0]
+                               {'data': Binary(b'yo')})[0][0]
             cnx.commit()
 
         with self.admin_access.web_request(rollbackfirst=True) as req:
@@ -362,11 +358,11 @@
                         '__type:X': 'Salesterm',
                         '_cw_entity_fields:X': 'amount-subject,described_by_test-subject',
                         'amount-subject:X': u'-10',
-                        'described_by_test-subject:X': unicode(feid),
+                        'described_by_test-subject:X': text_type(feid),
                     }
             with self.assertRaises(ValidationError) as cm:
                 self.ctrl_publish(req)
-            cm.exception.translate(unicode)
+            cm.exception.translate(text_type)
             self.assertEqual({'amount-subject': 'value -10 must be >= 0'},
                              cm.exception.errors)
 
@@ -375,11 +371,11 @@
                         '__type:X': 'Salesterm',
                         '_cw_entity_fields:X': 'amount-subject,described_by_test-subject',
                         'amount-subject:X': u'110',
-                        'described_by_test-subject:X': unicode(feid),
+                        'described_by_test-subject:X': text_type(feid),
                         }
             with self.assertRaises(ValidationError) as cm:
                 self.ctrl_publish(req)
-            cm.exception.translate(unicode)
+            cm.exception.translate(text_type)
             self.assertEqual(cm.exception.errors, {'amount-subject': 'value 110 must be <= 100'})
 
         with self.admin_access.web_request(rollbackfirst=True) as req:
@@ -387,7 +383,7 @@
                         '__type:X': 'Salesterm',
                         '_cw_entity_fields:X': 'amount-subject,described_by_test-subject',
                         'amount-subject:X': u'10',
-                        'described_by_test-subject:X': unicode(feid),
+                        'described_by_test-subject:X': text_type(feid),
                         }
             self.expect_redirect_handle_request(req, 'edit')
             # should be redirected on the created
@@ -400,31 +396,31 @@
         constrained attributes"""
         with self.admin_access.repo_cnx() as cnx:
             feid = cnx.execute('INSERT File X: X data_name "toto.txt", X data %(data)s',
-                               {'data': Binary('yo')})[0][0]
+                               {'data': Binary(b'yo')})[0][0]
             seid = cnx.create_entity('Salesterm', amount=0, described_by_test=feid).eid
             cnx.commit()
 
         # ensure a value that violate a constraint is properly detected
         with self.admin_access.web_request(rollbackfirst=True) as req:
-            req.form = {'eid': [unicode(seid)],
+            req.form = {'eid': [text_type(seid)],
                         '__type:%s'%seid: 'Salesterm',
                         '_cw_entity_fields:%s'%seid: 'amount-subject',
                         'amount-subject:%s'%seid: u'-10',
                     }
             self.assertMultiLineEqual('''<script type="text/javascript">
  window.parent.handleFormValidationResponse('entityForm', null, null, [false, [%s, {"amount-subject": "value -10 must be >= 0"}], null], null);
-</script>'''%seid, self.ctrl_publish(req, 'validateform'))
+</script>'''%seid, self.ctrl_publish(req, 'validateform').decode('ascii'))
 
         # ensure a value that comply a constraint is properly processed
         with self.admin_access.web_request(rollbackfirst=True) as req:
-            req.form = {'eid': [unicode(seid)],
+            req.form = {'eid': [text_type(seid)],
                         '__type:%s'%seid: 'Salesterm',
                         '_cw_entity_fields:%s'%seid: 'amount-subject',
                         'amount-subject:%s'%seid: u'20',
                     }
             self.assertMultiLineEqual('''<script type="text/javascript">
  window.parent.handleFormValidationResponse('entityForm', null, null, [true, "http://testing.fr/cubicweb/view", null], null);
-</script>''', self.ctrl_publish(req, 'validateform'))
+</script>''', self.ctrl_publish(req, 'validateform').decode('ascii'))
             self.assertEqual(20, req.execute('Any V WHERE X amount V, X eid %(eid)s',
                                              {'eid': seid})[0][0])
 
@@ -433,7 +429,7 @@
                         '__type:X': 'Salesterm',
                         '_cw_entity_fields:X': 'amount-subject,described_by_test-subject',
                         'amount-subject:X': u'0',
-                        'described_by_test-subject:X': unicode(feid),
+                        'described_by_test-subject:X': text_type(feid),
                     }
 
             # ensure a value that is modified in an operation on a modify
@@ -452,11 +448,11 @@
             with self.temporary_appobjects(ValidationErrorInOpAfterHook):
                 self.assertMultiLineEqual('''<script type="text/javascript">
  window.parent.handleFormValidationResponse('entityForm', null, null, [false, ["X", {"amount-subject": "value -10 must be >= 0"}], null], null);
-</script>''', self.ctrl_publish(req, 'validateform'))
+</script>''', self.ctrl_publish(req, 'validateform').decode('ascii'))
 
             self.assertMultiLineEqual('''<script type="text/javascript">
  window.parent.handleFormValidationResponse('entityForm', null, null, [true, "http://testing.fr/cubicweb/view", null], null);
-</script>''', self.ctrl_publish(req, 'validateform'))
+</script>''', self.ctrl_publish(req, 'validateform').decode('ascii'))
 
     def test_req_pending_insert(self):
         """make sure req's pending insertions are taken into account"""
@@ -541,7 +537,7 @@
     def test_redirect_delete_button(self):
         with self.admin_access.web_request() as req:
             eid = req.create_entity('BlogEntry', title=u'hop', content=u'hop').eid
-            req.form = {'eid': unicode(eid), '__type:%s'%eid: 'BlogEntry',
+            req.form = {'eid': text_type(eid), '__type:%s'%eid: 'BlogEntry',
                         '__action_delete': ''}
             path, params = self.expect_redirect_handle_request(req, 'edit')
             self.assertEqual(path, 'blogentry')
@@ -550,14 +546,14 @@
             req.execute('SET X use_email E WHERE E eid %(e)s, X eid %(x)s',
                         {'x': req.user.eid, 'e': eid})
             req.cnx.commit()
-            req.form = {'eid': unicode(eid), '__type:%s'%eid: 'EmailAddress',
+            req.form = {'eid': text_type(eid), '__type:%s'%eid: 'EmailAddress',
                         '__action_delete': ''}
             path, params = self.expect_redirect_handle_request(req, 'edit')
             self.assertEqual(path, 'cwuser/admin')
             self.assertIn('_cwmsgid', params)
             eid1 = req.create_entity('BlogEntry', title=u'hop', content=u'hop').eid
             eid2 = req.create_entity('EmailAddress', address=u'hop@logilab.fr').eid
-            req.form = {'eid': [unicode(eid1), unicode(eid2)],
+            req.form = {'eid': [text_type(eid1), text_type(eid2)],
                         '__type:%s'%eid1: 'BlogEntry',
                         '__type:%s'%eid2: 'EmailAddress',
                         '__action_delete': ''}
@@ -607,13 +603,13 @@
             groupeids = sorted(eid
                                for eid, in req.execute('CWGroup G '
                                                        'WHERE G name in ("managers", "users")'))
-            groups = [unicode(eid) for eid in groupeids]
+            groups = [text_type(eid) for eid in groupeids]
             cwetypeeid = req.execute('CWEType X WHERE X name "CWEType"')[0][0]
-            basegroups = [unicode(eid)
+            basegroups = [text_type(eid)
                           for eid, in req.execute('CWGroup G '
                                                   'WHERE X read_permission G, X eid %(x)s',
                                                   {'x': cwetypeeid})]
-            cwetypeeid = unicode(cwetypeeid)
+            cwetypeeid = text_type(cwetypeeid)
             req.form = {
                 'eid':      cwetypeeid,
                 '__type:'+cwetypeeid:  'CWEType',
@@ -662,7 +658,7 @@
                         '_cw_entity_fields:X': 'login-subject,upassword-subject,in_group-subject',
                         'login-subject:X': u'adim',
                         'upassword-subject:X': u'toto', 'upassword-subject-confirm:X': u'toto',
-                        'in_group-subject:X': `gueid`,
+                        'in_group-subject:X': repr(gueid),
 
                         '__type:Y': 'EmailAddress',
                         '_cw_entity_fields:Y': 'address-subject,alias-subject,use_email-object',
@@ -737,7 +733,7 @@
 
                             '__type:Y': 'File',
                             '_cw_entity_fields:Y': 'data-subject',
-                            'data-subject:Y': (u'coucou.txt', Binary('coucou')),
+                            'data-subject:Y': (u'coucou.txt', Binary(b'coucou')),
                             }
                 values_by_eid = dict((eid, req.extract_entity_params(eid, minparams=2))
                                      for eid in req.edited_eids())
@@ -783,7 +779,7 @@
             rset = self.john.as_rset()
             rset.req = req
             source = ctrl.publish()
-            self.assertTrue(source.startswith('<div>'))
+            self.assertTrue(source.startswith(b'<div>'))
 
 #     def test_json_exec(self):
 #         rql = 'Any T,N WHERE T is Tag, T name N'
@@ -824,7 +820,7 @@
                 rset.req = req
                 source = ctrl.publish()
                 # maydel jscall
-                self.assertIn('ajaxBoxRemoveLinkedEntity', source)
+                self.assertIn(b'ajaxBoxRemoveLinkedEntity', source)
 
     def test_pending_insertion(self):
         with self.remote_calling('add_pending_inserts', [['12', 'tags', '13']]) as (_, req):
@@ -887,16 +883,16 @@
     # silly tests
     def test_external_resource(self):
         with self.remote_calling('external_resource', 'RSS_LOGO') as (res, _):
-            self.assertEqual(json_dumps(self.config.uiprops['RSS_LOGO']),
+            self.assertEqual(json_dumps(self.config.uiprops['RSS_LOGO']).encode('ascii'),
                              res)
 
     def test_i18n(self):
         with self.remote_calling('i18n', ['bimboom']) as (res, _):
-            self.assertEqual(json_dumps(['bimboom']), res)
+            self.assertEqual(json_dumps(['bimboom']).encode('ascii'), res)
 
     def test_format_date(self):
         with self.remote_calling('format_date', '2007-01-01 12:00:00') as (res, _):
-            self.assertEqual(json_dumps('2007/01/01'), res)
+            self.assertEqual(json_dumps('2007/01/01').encode('ascii'), res)
 
     def test_ajaxfunc_noparameter(self):
         @ajaxfunc
@@ -968,7 +964,7 @@
         def js_foo(self):
             return u'hello'
         with self.remote_calling('foo') as (res, _):
-            self.assertEqual(res, u'hello')
+            self.assertEqual(res, b'hello')
 
     def test_monkeypatch_jsoncontroller_xhtmlize(self):
         with self.assertRaises(RemoteCallFailed):
@@ -979,7 +975,7 @@
         def js_foo(self):
             return u'hello'
         with self.remote_calling('foo') as (res, _):
-            self.assertEqual(u'<div>hello</div>', res)
+            self.assertEqual(b'<div>hello</div>', res)
 
     def test_monkeypatch_jsoncontroller_jsonize(self):
         with self.assertRaises(RemoteCallFailed):
@@ -990,7 +986,7 @@
         def js_foo(self):
             return 12
         with self.remote_calling('foo') as (res, _):
-            self.assertEqual(res, '12')
+            self.assertEqual(res, b'12')
 
     def test_monkeypatch_jsoncontroller_stdfunc(self):
         @monkeypatch(JSonController)
@@ -998,7 +994,7 @@
         def js_reledit_form(self):
             return 12
         with self.remote_calling('reledit_form') as (res, _):
-            self.assertEqual(res, '12')
+            self.assertEqual(res, b'12')
 
 
 class UndoControllerTC(CubicWebTC):
@@ -1042,7 +1038,7 @@
         """
         with self.admin_access.web_request() as req:
             scheme, netloc, path, query, fragment = urlsplit(url)
-            query_dict = url_parse_query(query)
+            query_dict = parse_qs(query)
             expected_url = urljoin(req.base_url(), expected_path)
             self.assertEqual( urlunsplit((scheme, netloc, path, None, None)), expected_url)
 
@@ -1058,17 +1054,6 @@
                 result = controller.publish(rset=None)
             self.assertURLPath(cm.exception.location, rpath)
 
-    def test_redirect_default(self):
-        with self.admin_access.web_request() as req:
-            txuuid = self.txuuid_toto_email
-            req.form['txuuid'] = txuuid
-            req.session.data['breadcrumbs'] = [ urljoin(req.base_url(), path)
-                                                for path in ('tata', 'toto',)]
-            controller = self.vreg['controllers'].select('undo', req)
-            with self.assertRaises(Redirect) as cm:
-                result = controller.publish(rset=None)
-            self.assertURLPath(cm.exception.location, 'toto')
-
 
 class LoginControllerTC(CubicWebTC):
 
--- a/web/test/unittest_views_baseviews.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/test/unittest_views_baseviews.py	Thu Dec 10 12:34:15 2015 +0100
@@ -129,8 +129,8 @@
                 source_lines = [line.strip()
                                 for line in html_source.splitlines(False)
                                 if line.strip()]
-                self.assertListEqual(['<!DOCTYPE html>',
-                                      '<html xmlns:cubicweb="http://www.cubicweb.org" lang="en">'],
+                self.assertListEqual([b'<!DOCTYPE html>',
+                                      b'<html xmlns:cubicweb="http://www.cubicweb.org" lang="en">'],
                                      source_lines[:2])
 
     def test_set_doctype_no_reset_xmldecl(self):
@@ -151,9 +151,9 @@
                 source_lines = [line.strip()
                                 for line in html_source.splitlines(False)
                                 if line.strip()]
-                self.assertListEqual([html_doctype,
-                                      '<html xmlns:cubicweb="http://www.cubicweb.org" lang="cz">',
-                                      '<head>'],
+                self.assertListEqual([html_doctype.encode('ascii'),
+                                      b'<html xmlns:cubicweb="http://www.cubicweb.org" lang="cz">',
+                                      b'<head>'],
                                      source_lines[:3])
 
 if __name__ == '__main__':
--- a/web/test/unittest_views_csv.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/test/unittest_views_csv.py	Thu Dec 10 12:34:15 2015 +0100
@@ -30,19 +30,19 @@
             self.assertEqual(req.headers_out.getRawHeaders('content-type'),
                              ['text/comma-separated-values;charset=UTF-8'])
             expected_data = "String;COUNT(CWUser)\nguests;1\nmanagers;1"
-            self.assertMultiLineEqual(expected_data, data)
+            self.assertMultiLineEqual(expected_data, data.decode('utf-8'))
 
     def test_csvexport_on_empty_rset(self):
         """Should return the CSV header.
         """
         with self.admin_access.web_request() as req:
-            rset = req.execute('Any GN,COUNT(X) GROUPBY GN ORDERBY GN '
-                               'WHERE X in_group G, G name GN, X login "Miles"')
+            rset = req.execute(u'Any GN,COUNT(X) GROUPBY GN ORDERBY GN '
+                                'WHERE X in_group G, G name GN, X login "Miles"')
             data = self.view('csvexport', rset, req=req)
             self.assertEqual(req.headers_out.getRawHeaders('content-type'),
                              ['text/comma-separated-values;charset=UTF-8'])
             expected_data = "String;COUNT(CWUser)"
-            self.assertMultiLineEqual(expected_data, data)
+            self.assertMultiLineEqual(expected_data, data.decode('utf-8'))
 
 
 if __name__ == '__main__':
--- a/web/test/unittest_views_editforms.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/test/unittest_views_editforms.py	Thu Dec 10 12:34:15 2015 +0100
@@ -255,4 +255,3 @@
 
 if __name__ == '__main__':
     unittest_main()
-
--- a/web/test/unittest_views_errorform.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/test/unittest_views_errorform.py	Thu Dec 10 12:34:15 2015 +0100
@@ -50,8 +50,8 @@
                     req.data['excinfo'] = sys.exc_info()
                     req.data['ex'] = e
                     html = self.view('error', req=req)
-                    self.failUnless(re.search(r'^<input name="__signature" type="hidden" '
-                                              'value="[0-9a-f]{32}" />$',
+                    self.assertTrue(re.search(b'^<input name="__signature" type="hidden" '
+                                              b'value="[0-9a-f]{32}" />$',
                                               html.source, re.M))
 
 
--- a/web/test/unittest_views_json.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/test/unittest_views_json.py	Thu Dec 10 12:34:15 2015 +0100
@@ -16,12 +16,14 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
+from six import binary_type
+
 from cubicweb.devtools.testlib import CubicWebTC
 
 
 class JsonViewsTC(CubicWebTC):
     anonymize = True
-    res_jsonp_data = '[["guests", 1]]'
+    res_jsonp_data = b'[["guests", 1]]'
 
     def setUp(self):
         super(JsonViewsTC, self).setUp()
@@ -36,7 +38,7 @@
 
     def test_json_rsetexport_empty_rset(self):
         with self.admin_access.web_request() as req:
-            rset = req.execute('Any X WHERE X is CWUser, X login "foobarbaz"')
+            rset = req.execute(u'Any X WHERE X is CWUser, X login "foobarbaz"')
             data = self.view('jsonexport', rset, req=req)
             self.assertEqual(req.headers_out.getRawHeaders('content-type'), ['application/json'])
             self.assertListEqual(data, [])
@@ -47,10 +49,10 @@
                              'rql': u'Any GN,COUNT(X) GROUPBY GN ORDERBY GN '
                              'WHERE X in_group G, G name GN'})
             data = self.ctrl_publish(req, ctrl='jsonp')
-            self.assertIsInstance(data, str)
+            self.assertIsInstance(data, binary_type)
             self.assertEqual(req.headers_out.getRawHeaders('content-type'), ['application/javascript'])
             # because jsonp anonymizes data, only 'guests' group should be found
-            self.assertEqual(data, 'foo(%s)' % self.res_jsonp_data)
+            self.assertEqual(data, b'foo(' + self.res_jsonp_data + b')')
 
     def test_json_rsetexport_with_jsonp_and_bad_vid(self):
         with self.admin_access.web_request() as req:
@@ -61,7 +63,7 @@
             data = self.ctrl_publish(req, ctrl='jsonp')
             self.assertEqual(req.headers_out.getRawHeaders('content-type'), ['application/javascript'])
             # result should be plain json, not the table view
-            self.assertEqual(data, 'foo(%s)' % self.res_jsonp_data)
+            self.assertEqual(data, b'foo(' + self.res_jsonp_data + b')')
 
     def test_json_ersetexport(self):
         with self.admin_access.web_request() as req:
@@ -71,7 +73,7 @@
             self.assertEqual(data[0]['name'], 'guests')
             self.assertEqual(data[1]['name'], 'managers')
 
-            rset = req.execute('Any G WHERE G is CWGroup, G name "foo"')
+            rset = req.execute(u'Any G WHERE G is CWGroup, G name "foo"')
             data = self.view('ejsonexport', rset, req=req)
             self.assertEqual(req.headers_out.getRawHeaders('content-type'), ['application/json'])
             self.assertEqual(data, [])
@@ -79,7 +81,7 @@
 
 class NotAnonymousJsonViewsTC(JsonViewsTC):
     anonymize = False
-    res_jsonp_data = '[["guests", 1], ["managers", 1]]'
+    res_jsonp_data = b'[["guests", 1], ["managers", 1]]'
 
 if __name__ == '__main__':
     from logilab.common.testlib import unittest_main
--- a/web/test/unittest_views_searchrestriction.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/test/unittest_views_searchrestriction.py	Thu Dec 10 12:34:15 2015 +0100
@@ -37,62 +37,62 @@
 
     @property
     def select(self):
-        return self.parse('Any B,(NOW - CD),S,V,U,GROUP_CONCAT(TN),VN,P,CD,BMD '
-                          'GROUPBY B,CD,S,V,U,VN,P,BMD '
-                          'WHERE B in_state S, B creation_date CD, '
-                          'B modification_date BMD, T? tags B, T name TN, '
-                          'V? bookmarked_by B, V title VN, B created_by U?, '
-                          'B in_group P, P name "managers"')
+        return self.parse(u'Any B,(NOW - CD),S,V,U,GROUP_CONCAT(TN),VN,P,CD,BMD '
+                           'GROUPBY B,CD,S,V,U,VN,P,BMD '
+                           'WHERE B in_state S, B creation_date CD, '
+                           'B modification_date BMD, T? tags B, T name TN, '
+                           'V? bookmarked_by B, V title VN, B created_by U?, '
+                           'B in_group P, P name "managers"')
 
     def test_1(self):
         self.assertEqual(self._generate(self.select, 'in_state', 'subject', 'name'),
-                          "DISTINCT Any A,C ORDERBY C WHERE B in_group P, P name 'managers', "
-                          "B in_state A, B is CWUser, A name C")
+                         'DISTINCT Any A,C ORDERBY C WHERE B in_group P, P name "managers", '
+                         'B in_state A, B is CWUser, A name C')
 
     def test_2(self):
         self.assertEqual(self._generate(self.select, 'tags', 'object', 'name'),
-                          "DISTINCT Any A,C ORDERBY C WHERE B in_group P, P name 'managers', "
-                          "A tags B, B is CWUser, A name C")
+                         'DISTINCT Any A,C ORDERBY C WHERE B in_group P, P name "managers", '
+                         'A tags B, B is CWUser, A name C')
 
     def test_3(self):
         self.assertEqual(self._generate(self.select, 'created_by', 'subject', 'login'),
-                          "DISTINCT Any A,C ORDERBY C WHERE B in_group P, P name 'managers', "
-                          "B created_by A, B is CWUser, A login C")
+                         'DISTINCT Any A,C ORDERBY C WHERE B in_group P, P name "managers", '
+                         'B created_by A, B is CWUser, A login C')
 
     def test_4(self):
-        self.assertEqual(self._generate(self.parse('Any X WHERE X is CWUser'), 'created_by', 'subject', 'login'),
+        self.assertEqual(self._generate(self.parse(u'Any X WHERE X is CWUser'), 'created_by', 'subject', 'login'),
                           "DISTINCT Any A,B ORDERBY B WHERE X is CWUser, X created_by A, A login B")
 
     def test_5(self):
-        self.assertEqual(self._generate(self.parse('Any X,L WHERE X is CWUser, X login L'), 'created_by', 'subject', 'login'),
+        self.assertEqual(self._generate(self.parse(u'Any X,L WHERE X is CWUser, X login L'), 'created_by', 'subject', 'login'),
                           "DISTINCT Any A,B ORDERBY B WHERE X is CWUser, X created_by A, A login B")
 
     def test_nonregr1(self):
-        select = self.parse('Any T,V WHERE T bookmarked_by V?, '
-                            'V in_state VS, VS name "published", T created_by U')
+        select = self.parse(u'Any T,V WHERE T bookmarked_by V?, '
+                             'V in_state VS, VS name "published", T created_by U')
         self.assertEqual(self._generate(select, 'created_by', 'subject', 'login'),
                           "DISTINCT Any A,B ORDERBY B WHERE T created_by U, "
                           "T created_by A, T is Bookmark, A login B")
 
     def test_nonregr2(self):
         #'DISTINCT Any X,TMP,N WHERE P name TMP, X version_of P, P is Project, X is Version, not X in_state S,S name "published", X num N ORDERBY TMP,N'
-        select = self.parse('DISTINCT Any V,TN,L ORDERBY TN,L WHERE T nom TN, V connait T, T is Personne, V is CWUser,'
-                            'NOT V in_state VS, VS name "published", V login L')
+        select = self.parse(u'DISTINCT Any V,TN,L ORDERBY TN,L WHERE T nom TN, V connait T, T is Personne, V is CWUser,'
+                             'NOT V in_state VS, VS name "published", V login L')
         rschema = self.schema['connait']
-        for rdefs in rschema.rdefs.itervalues():
+        for rdefs in rschema.rdefs.values():
             rdefs.cardinality =  '++'
         try:
             self.assertEqual(self._generate(select, 'in_state', 'subject', 'name'),
-                              "DISTINCT Any A,B ORDERBY B WHERE V is CWUser, "
-                              "NOT EXISTS(V in_state VS), VS name 'published', "
-                              "V in_state A, A name B")
+                             'DISTINCT Any A,B ORDERBY B WHERE V is CWUser, '
+                             'NOT EXISTS(V in_state VS), VS name "published", '
+                             'V in_state A, A name B')
         finally:
-            for rdefs in rschema.rdefs.itervalues():
+            for rdefs in rschema.rdefs.values():
                 rdefs.cardinality =  '**'
 
     def test_nonregr3(self):
         #'DISTINCT Any X,TMP,N WHERE P name TMP, X version_of P, P is Project, X is Version, not X in_state S,S name "published", X num N ORDERBY TMP,N'
-        select = self.parse('DISTINCT Any X, MAX(Y) GROUPBY X WHERE X is CWUser, Y is Bookmark, X in_group A')
+        select = self.parse(u'DISTINCT Any X, MAX(Y) GROUPBY X WHERE X is CWUser, Y is Bookmark, X in_group A')
         self.assertEqual(self._generate(select, 'in_group', 'subject', 'name'),
                           "DISTINCT Any B,C ORDERBY C WHERE X is CWUser, X in_group B, B name C")
 
--- a/web/test/unittest_views_staticcontrollers.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/test/unittest_views_staticcontrollers.py	Thu Dec 10 12:34:15 2015 +0100
@@ -70,12 +70,21 @@
         with self._publish_static_files(fname) as req:
             self.assertEqual(200, req.status_out)
             self.assertIn('last-modified', req.headers_out)
+            self.assertIn('expires', req.headers_out)
+            self.assertEqual(req.get_response_header('cache-control'),
+                             {'max-age': 604800})
         next_headers = {
             'if-modified-since': req.get_response_header('last-modified', raw=True),
         }
         with self._publish_static_files(fname, next_headers) as req:
             self.assertEqual(304, req.status_out)
 
+    def _check_datafile_redirect(self, fname, expected):
+        with self._publish_static_files(fname) as req:
+            self.assertEqual(302, req.status_out)
+            self.assertEqual(req.get_response_header('location'),
+                             req.base_url() + expected)
+
     def _check_no_datafile(self, fname):
         with self._publish_static_files(fname) as req:
             self.assertEqual(404, req.status_out)
@@ -90,10 +99,12 @@
             self._check_no_datafile('data/%s/cubicweb.css' % ('0'*len(hash)))
 
         with tempattr(self.vreg.config, 'mode', 'notest'):
-            self._check_datafile_ok('data/cubicweb.css')
+            self.config._init_base_url()  # reset config.datadir_url
+            self._check_datafile_redirect('data/cubicweb.css', 'data/%s/cubicweb.css' % hash)
             self._check_datafile_ok('data/%s/cubicweb.css' % hash)
-            self._check_no_datafile('data/does/not/exist')
-            self._check_no_datafile('data/%s/cubicweb.css' % ('0'*len(hash)))
+            self._check_no_datafile('data/%s/does/not/exist' % hash)
+            self._check_datafile_redirect('data/%s/does/not/exist' % ('0'*len(hash)),
+                                          'data/%s/%s/does/not/exist' % (hash, '0'*len(hash)))
 
 
 class ConcatFilesTC(CubicWebTC):
@@ -120,12 +131,12 @@
             yield res, req
 
     def expected_content(self, js_files):
-        content = u''
+        content = b''
         for js_file in js_files:
             dirpath, rid = self.config.locate_resource(js_file)
             if dirpath is not None: # ignore resources not found
-                with open(osp.join(dirpath, rid)) as f:
-                    content += f.read() + '\n'
+                with open(osp.join(dirpath, rid), 'rb') as f:
+                    content += f.read() + b'\n'
         return content
 
     def test_cache(self):
@@ -162,4 +173,3 @@
 if __name__ == '__main__':
     from logilab.common.testlib import unittest_main
     unittest_main()
-
--- a/web/test/unittest_viewselector.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/test/unittest_viewselector.py	Thu Dec 10 12:34:15 2015 +0100
@@ -17,6 +17,7 @@
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """XXX rename, split, reorganize this"""
+from __future__ import print_function
 
 from logilab.common.testlib import unittest_main
 
@@ -76,9 +77,9 @@
         try:
             self.assertSetEqual(list(content), expected)
         except Exception:
-            print registry, sorted(expected), sorted(content)
-            print 'no more', [v for v in expected if not v in content]
-            print 'missing', [v for v in content if not v in expected]
+            print(registry, sorted(expected), sorted(content))
+            print('no more', [v for v in expected if not v in content])
+            print('missing', [v for v in content if not v in expected])
             raise
 
     def setUp(self):
@@ -421,7 +422,7 @@
 
     def test_interface_selector(self):
         with self.admin_access.web_request() as req:
-            req.create_entity('File', data_name=u'bim.png', data=Binary('bim'))
+            req.create_entity('File', data_name=u'bim.png', data=Binary(b'bim'))
             # image primary view priority
             rset = req.execute('File X WHERE X data_name "bim.png"')
             self.assertIsInstance(self.vreg['views'].select('primary', req, rset=rset),
@@ -430,21 +431,21 @@
 
     def test_score_entity_selector(self):
         with self.admin_access.web_request() as req:
-            req.create_entity('File', data_name=u'bim.png', data=Binary('bim'))
+            req.create_entity('File', data_name=u'bim.png', data=Binary(b'bim'))
             # image/ehtml primary view priority
             rset = req.execute('File X WHERE X data_name "bim.png"')
             self.assertIsInstance(self.vreg['views'].select('image', req, rset=rset),
                                   idownloadable.ImageView)
             self.assertRaises(NoSelectableObject, self.vreg['views'].select, 'ehtml', req, rset=rset)
 
-            fileobj = req.create_entity('File', data_name=u'bim.html', data=Binary('<html>bam</html'))
+            fileobj = req.create_entity('File', data_name=u'bim.html', data=Binary(b'<html>bam</html'))
             # image/ehtml primary view priority
             rset = req.execute('File X WHERE X data_name "bim.html"')
             self.assertIsInstance(self.vreg['views'].select('ehtml', req, rset=rset),
                                   idownloadable.EHTMLView)
             self.assertRaises(NoSelectableObject, self.vreg['views'].select, 'image', req, rset=rset)
 
-            fileobj = req.create_entity('File', data_name=u'bim.txt', data=Binary('boum'))
+            fileobj = req.create_entity('File', data_name=u'bim.txt', data=Binary(b'boum'))
             # image/ehtml primary view priority
             rset = req.execute('File X WHERE X data_name "bim.txt"')
             self.assertRaises(NoSelectableObject, self.vreg['views'].select, 'image', req, rset=rset)
@@ -461,7 +462,7 @@
                 obj = self.vreg['views'].select(vid, req, rset=rset, **args)
                 return obj.render(**args)
             except Exception:
-                print vid, rset, args
+                print(vid, rset, args)
                 raise
 
     def test_form(self):
@@ -476,12 +477,12 @@
 
 
     def test_properties(self):
-        self.assertEqual(sorted(k for k in self.vreg['propertydefs'].iterkeys()
+        self.assertEqual(sorted(k for k in self.vreg['propertydefs']
                                 if k.startswith('ctxcomponents.edit_box')),
                          ['ctxcomponents.edit_box.context',
                           'ctxcomponents.edit_box.order',
                           'ctxcomponents.edit_box.visible'])
-        self.assertEqual([k for k in self.vreg['propertyvalues'].iterkeys()
+        self.assertEqual([k for k in self.vreg['propertyvalues']
                           if not k.startswith('system.version')],
                          [])
         self.assertEqual(self.vreg.property_value('ctxcomponents.edit_box.visible'), True)
--- a/web/test/unittest_webconfig.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/test/unittest_webconfig.py	Thu Dec 10 12:34:15 2015 +0100
@@ -56,5 +56,3 @@
 
 if __name__ == '__main__':
     unittest_main()
-
-
--- a/web/uicfg.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/uicfg.py	Thu Dec 10 12:34:15 2015 +0100
@@ -26,4 +26,3 @@
 
 warn('[3.16] moved to cubicweb.web.views.uicfg',
      DeprecationWarning, stacklevel=2)
-
--- a/web/uihelper.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/uihelper.py	Thu Dec 10 12:34:15 2015 +0100
@@ -45,6 +45,7 @@
 """
 __docformat__ = "restructuredtext en"
 
+from six import add_metaclass
 
 from logilab.common.deprecation import deprecated
 from cubicweb.web.views import uicfg
@@ -93,6 +94,7 @@
         super(meta_formconfig, cls).__init__(name, bases, classdict)
 
 
+@add_metaclass(meta_formconfig)
 class FormConfig:
     """helper base class to define uicfg rules on a given entity type.
 
@@ -162,7 +164,6 @@
       inlined = ('use_email',)
 
     """
-    __metaclass__ = meta_formconfig
     formtype = 'main'
     etype = None # must be defined in concrete subclasses
     hidden = ()
--- a/web/views/__init__.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/__init__.py	Thu Dec 10 12:34:15 2015 +0100
@@ -23,6 +23,8 @@
 import sys
 import tempfile
 
+from six import add_metaclass
+
 from rql import nodes
 from logilab.mtconverter import xml_escape
 from logilab.common.deprecation import class_deprecated
@@ -77,7 +79,7 @@
     #'text/xml': 'xml',
     # XXX rss, owl...
 }
-def vid_from_rset(req, rset, schema):
+def vid_from_rset(req, rset, schema, check_table=True):
     """given a result set, return a view id"""
     if rset is None:
         return 'index'
@@ -90,7 +92,7 @@
         return 'noresult'
     # entity result set
     if not schema.eschema(rset.description[0][0]).final:
-        if need_table_view(rset, schema):
+        if check_table and need_table_view(rset, schema):
             return 'table'
         if nb_rows == 1:
             if req.search_state[0] == 'normal':
@@ -127,8 +129,8 @@
 
 
 
+@add_metaclass(class_deprecated)
 class TmpFileViewMixin(object):
-    __metaclass__ = class_deprecated
     __deprecation_warning__ = '[3.18] %(cls)s is deprecated'
     binary = True
     content_type = 'application/octet-stream'
--- a/web/views/actions.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/actions.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,7 +18,7 @@
 """Set of HTML base actions"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from warnings import warn
 
@@ -76,7 +76,7 @@
             return 0
         select = rqlst.children[0]
         if len(select.defined_vars) == 1 and len(select.solutions) == 1:
-            rset._searched_etype = select.solutions[0].itervalues().next()
+            rset._searched_etype = next(iter(select.solutions[0].values()))
             eschema = req.vreg.schema.eschema(rset._searched_etype)
             if not (eschema.final or eschema.is_subobject(strict=True)) \
                    and eschema.has_perm(req, 'add'):
--- a/web/views/ajaxcontroller.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/ajaxcontroller.py	Thu Dec 10 12:34:15 2015 +0100
@@ -66,6 +66,8 @@
 from warnings import warn
 from functools import partial
 
+from six import PY2, text_type
+
 from logilab.common.date import strptime
 from logilab.common.registry import yes
 from logilab.common.deprecation import deprecated
@@ -84,7 +86,7 @@
     if extraargs is None:
         return {}
     # we receive unicode keys which is not supported by the **syntax
-    return dict((str(key), value) for key, value in extraargs.iteritems())
+    return dict((str(key), value) for key, value in extraargs.items())
 
 
 class AjaxController(Controller):
@@ -117,7 +119,9 @@
             raise RemoteCallFailed('no method specified')
         # 1/ check first for old-style (JSonController) ajax func for bw compat
         try:
-            func = getattr(basecontrollers.JSonController, 'js_%s' % fname).im_func
+            func = getattr(basecontrollers.JSonController, 'js_%s' % fname)
+            if PY2:
+                func = func.__func__
             func = partial(func, self)
         except AttributeError:
             # 2/ check for new-style (AjaxController) ajax func
@@ -150,7 +154,7 @@
         if result is None:
             return ''
         # get unicode on @htmlize methods, encoded string on @jsonize methods
-        elif isinstance(result, unicode):
+        elif isinstance(result, text_type):
             return result.encode(self._cw.encoding)
         return result
 
--- a/web/views/authentication.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/authentication.py	Thu Dec 10 12:34:15 2015 +0100
@@ -19,12 +19,9 @@
 
 __docformat__ = "restructuredtext en"
 
-from threading import Lock
-
-from logilab.common.decorators import clear_cache
 from logilab.common.deprecation import class_renamed
 
-from cubicweb import AuthenticationError, BadConnectionId
+from cubicweb import AuthenticationError
 from cubicweb.view import Component
 from cubicweb.web import InvalidSession
 
@@ -101,41 +98,11 @@
     '("ie" instead of "ei")')
 
 
-class AbstractAuthenticationManager(Component):
-    """authenticate user associated to a request and check session validity"""
-    __abstract__ = True
-    __regid__ = 'authmanager'
 
-    def __init__(self, repo):
-        self.vreg = repo.vreg
-
-    def validate_session(self, req, session):
-        """check session validity, reconnecting it to the repository if the
-        associated connection expired in the repository side (hence the
-        necessity for this method).
-
-        raise :exc:`InvalidSession` if session is corrupted for a reason or
-        another and should be closed
-        """
-        raise NotImplementedError()
-
-    def authenticate(self, req):
-        """authenticate user using connection information found in the request,
-        and return corresponding a :class:`~cubicweb.dbapi.Connection` instance,
-        as well as login and authentication information dictionary used to open
-        the connection.
-
-        raise :exc:`cubicweb.AuthenticationError` if authentication failed
-        (no authentication info found or wrong user/password)
-        """
-        raise NotImplementedError()
-
-
-class RepositoryAuthenticationManager(AbstractAuthenticationManager):
+class RepositoryAuthenticationManager(object):
     """authenticate user associated to a request and check session validity"""
 
     def __init__(self, repo):
-        super(RepositoryAuthenticationManager, self).__init__(repo)
         self.repo = repo
         vreg = repo.vreg
         self.log_queries = vreg.config['query-log-file']
@@ -205,4 +172,3 @@
     def _authenticate(self, login, authinfo):
         sessionid = self.repo.connect(login, **authinfo)
         return self.repo._sessions[sessionid]
-
--- a/web/views/autoform.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/autoform.py	Thu Dec 10 12:34:15 2015 +0100
@@ -119,10 +119,12 @@
 """
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from warnings import warn
 
+from six.moves import range
+
 from logilab.mtconverter import xml_escape
 from logilab.common.decorators import iclassmethod, cached
 from logilab.common.deprecation import deprecated
@@ -355,7 +357,7 @@
             self.w(self._cw._('no such entity type %s') % self.etype)
             return
         entity = cls(self._cw)
-        entity.eid = self._cw.varmaker.next()
+        entity.eid = next(self._cw.varmaker)
         return entity
 
     def call(self, i18nctx, **kwargs):
@@ -491,7 +493,8 @@
     pendings.remove( (int(eidfrom), rel, int(eidto)) )
 
 @ajaxfunc(output_type='json')
-def remove_pending_insert(self, (eidfrom, rel, eidto)):
+def remove_pending_insert(self, args):
+    eidfrom, rel, eidto = args
     _remove_pending(self._cw, eidfrom, rel, eidto, 'insert')
 
 @ajaxfunc(output_type='json')
@@ -500,11 +503,13 @@
         _add_pending(self._cw, eidfrom, rel, eidto, 'insert')
 
 @ajaxfunc(output_type='json')
-def remove_pending_delete(self, (eidfrom, rel, eidto)):
+def remove_pending_delete(self, args):
+    eidfrom, rel, eidto = args
     _remove_pending(self._cw, eidfrom, rel, eidto, 'delete')
 
 @ajaxfunc(output_type='json')
-def add_pending_delete(self, (eidfrom, rel, eidto)):
+def add_pending_delete(self, args):
+    eidfrom, rel, eidto = args
     _add_pending(self._cw, eidfrom, rel, eidto, 'delete')
 
 
@@ -608,7 +613,7 @@
                     toggleable_rel_link_func = toggleable_relation_link
                 else:
                     toggleable_rel_link_func = lambda x, y, z: u''
-                for row in xrange(rset.rowcount):
+                for row in range(rset.rowcount):
                     nodeid = relation_id(entity.eid, rschema, role,
                                          rset[row][0])
                     if nodeid in pending_deletes:
@@ -737,7 +742,8 @@
     copy_nav_params = True
     form_buttons = [fw.SubmitButton(),
                     fw.Button(stdmsgs.BUTTON_APPLY, cwaction='apply'),
-                    fw.Button(stdmsgs.BUTTON_CANCEL, cwaction='cancel')]
+                    fw.Button(stdmsgs.BUTTON_CANCEL,
+                              {'class': fw.Button.css_class + ' cwjs-edition-cancel'})]
     # for attributes selection when searching in uicfg.autoform_section
     formtype = 'main'
     # set this to a list of [(relation, role)] if you want to explictily tell
@@ -1048,4 +1054,4 @@
             AutomaticEntityForm.error('field for %s %s may not be found in schema' % (rtype, role))
             return None
 
-    vreg.register_all(globals().itervalues(), __name__)
+    vreg.register_all(globals().values(), __name__)
--- a/web/views/basecomponents.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/basecomponents.py	Thu Dec 10 12:34:15 2015 +0100
@@ -21,7 +21,7 @@
 * the logged user link
 """
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from logilab.mtconverter import xml_escape
 from logilab.common.registry import yes
--- a/web/views/basecontrollers.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/basecontrollers.py	Thu Dec 10 12:34:15 2015 +0100
@@ -20,10 +20,12 @@
 """
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from warnings import warn
 
+from six import text_type
+
 from logilab.common.deprecation import deprecated
 
 from cubicweb import (NoSelectableObject, ObjectNotFound, ValidationError,
@@ -124,7 +126,6 @@
     def publish(self, rset=None):
         """publish a request, returning an encoded string"""
         view, rset = self._select_view_and_rset(rset)
-        self.add_to_breadcrumbs(view)
         view.set_http_cache_headers()
         if self._cw.is_client_cache_valid():
             return ''
@@ -158,13 +159,6 @@
             view = req.vreg['views'].select(vid, req, rset=rset)
         return view, rset
 
-    def add_to_breadcrumbs(self, view):
-        # update breadcrumbs **before** validating cache, unless the view
-        # specifies explicitly it should not be added to breadcrumb or the
-        # view is a binary view
-        if view.add_to_breadcrumbs and not view.binary:
-            self._cw.update_breadcrumbs()
-
     def execute_linkto(self, eid=None):
         """XXX __linkto parameter may cause security issue
 
@@ -233,7 +227,7 @@
     except Exception as ex:
         req.cnx.rollback()
         req.exception('unexpected error while validating form')
-        return (False, str(ex).decode('utf-8'), ctrl._edited_entity)
+        return (False, text_type(ex), ctrl._edited_entity)
     return (False, '???', None)
 
 
@@ -255,9 +249,8 @@
         # XXX unclear why we have a separated controller here vs
         # js_validate_form on the json controller
         status, args, entity = _validate_form(self._cw, self._cw.vreg)
-        domid = self._cw.form.get('__domid', 'entityForm').encode(
-            self._cw.encoding)
-        return self.response(domid, status, args, entity)
+        domid = self._cw.form.get('__domid', 'entityForm')
+        return self.response(domid, status, args, entity).encode(self._cw.encoding)
 
 
 class JSonController(Controller):
@@ -306,5 +299,4 @@
     def redirect(self, msg=None):
         req = self._cw
         msg = msg or req._("transaction undone")
-        self._return_to_lastpage( dict(_cwmsgid= req.set_redirect_message(msg)) )
-
+        self._redirect({'_cwmsgid': req.set_redirect_message(msg)})
--- a/web/views/basetemplates.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/basetemplates.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,7 +18,7 @@
 """default templates for CubicWeb web client"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from logilab.mtconverter import xml_escape
 from logilab.common.deprecation import class_renamed
--- a/web/views/baseviews.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/baseviews.py	Thu Dec 10 12:34:15 2015 +0100
@@ -76,11 +76,13 @@
 """
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from datetime import timedelta
 from warnings import warn
 
+from six.moves import range
+
 from rql import nodes
 
 from logilab.mtconverter import TransformError, xml_escape
@@ -231,8 +233,8 @@
         """
         rset = self.cw_rset
         if rset is None:
-            raise NotImplementedError, self
-        for i in xrange(len(rset)):
+            raise NotImplementedError(self)
+        for i in range(len(rset)):
             self.wview(self.__regid__, rset, row=i, **kwargs)
             if len(rset) > 1:
                 self.w(u"\n")
@@ -314,7 +316,7 @@
             self.w(u'<ul>\n')
         else:
             self.w(u'<ul%s class="%s">\n' % (listid, klass or 'section'))
-        for i in xrange(self.cw_rset.rowcount):
+        for i in range(self.cw_rset.rowcount):
             self.cell_call(row=i, col=0, vid=subvid, klass=klass, **kwargs)
         self.w(u'</ul>\n')
         if title:
@@ -393,7 +395,7 @@
 
     @property
     def title(self):
-        etype = iter(self.cw_rset.column_types(0)).next()
+        etype = next(iter(self.cw_rset.column_types(0)))
         return display_name(self._cw, etype, form='plural')
 
     def call(self, **kwargs):
@@ -427,7 +429,7 @@
     def call(self, subvid=None, **kwargs):
         kwargs['vid'] = subvid
         rset = self.cw_rset
-        for i in xrange(len(rset)):
+        for i in range(len(rset)):
             self.cell_call(i, 0, **kwargs)
             if i < rset.rowcount-1:
                 self.w(self.separator)
--- a/web/views/bookmark.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/bookmark.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,7 +18,7 @@
 """Primary view for bookmarks + user's bookmarks box"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from logilab.mtconverter import xml_escape
 
--- a/web/views/boxes.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/boxes.py	Thu Dec 10 12:34:15 2015 +0100
@@ -26,10 +26,12 @@
 * startup views box
 """
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from warnings import warn
 
+from six import text_type, add_metaclass
+
 from logilab.mtconverter import xml_escape
 from logilab.common.deprecation import class_deprecated
 
@@ -93,7 +95,7 @@
             etypes = self.cw_rset.column_types(0)
             if len(etypes) == 1:
                 plural = self.cw_rset.rowcount > 1 and 'plural' or ''
-                etypelabel = display_name(self._cw, iter(etypes).next(), plural)
+                etypelabel = display_name(self._cw, next(iter(etypes)), plural)
                 title = u'%s - %s' % (title, etypelabel.lower())
         w(title)
 
@@ -216,7 +218,7 @@
 
     @property
     def domid(self):
-        return super(RsetBox, self).domid + unicode(abs(id(self))) + unicode(abs(id(self.cw_rset)))
+        return super(RsetBox, self).domid + text_type(abs(id(self))) + text_type(abs(id(self.cw_rset)))
 
     def render_title(self, w):
         w(self.cw_extra_kwargs['title'])
@@ -231,9 +233,9 @@
 
  # helper classes ##############################################################
 
+@add_metaclass(class_deprecated)
 class SideBoxView(EntityView):
     """helper view class to display some entities in a sidebox"""
-    __metaclass__ = class_deprecated
     __deprecation_warning__ = '[3.10] SideBoxView is deprecated, use RsetBox instead (%(cls)s)'
 
     __regid__ = 'sidebox'
--- a/web/views/calendar.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/calendar.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,7 +18,7 @@
 """html calendar views"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 import copy
 from datetime import timedelta
--- a/web/views/csvexport.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/csvexport.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,7 +18,10 @@
 """csv export views"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
+
+from six import PY2
+from six.moves import range
 
 from cubicweb.schema import display_name
 from cubicweb.predicates import any_rset, empty_rset
@@ -29,7 +32,7 @@
     """mixin class for CSV views"""
     templatable = False
     content_type = "text/comma-separated-values"
-    binary = True # avoid unicode assertion
+    binary = PY2 # python csv module is unicode aware in py3k
     csv_params = {'dialect': 'excel',
                   'quotechar': '"',
                   'delimiter': ';',
@@ -88,7 +91,7 @@
         rows_by_type = {}
         writer = self.csvwriter()
         rowdef_by_type = {}
-        for index in xrange(len(self.cw_rset)):
+        for index in range(len(self.cw_rset)):
             entity = self.cw_rset.complete_entity(index)
             if entity.e_schema not in rows_by_type:
                 rowdef_by_type[entity.e_schema] = [rs for rs, at in entity.e_schema.attribute_definitions()
@@ -98,8 +101,7 @@
             rows = rows_by_type[entity.e_schema]
             rows.append([entity.printable_value(rs.type, format='text/plain')
                          for rs in rowdef_by_type[entity.e_schema]])
-        for rows in rows_by_type.itervalues():
+        for rows in rows_by_type.values():
             writer.writerows(rows)
             # use two empty lines as separator
             writer.writerows([[], []])
-
--- a/web/views/cwproperties.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/cwproperties.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,7 +18,7 @@
 """Specific views for CWProperty (eg site/user preferences"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from logilab.mtconverter import xml_escape
 
@@ -119,10 +119,10 @@
         _ = self._cw._
         self.w(u'<h1>%s</h1>\n' % _(self.title))
         for label, group, form in sorted((_(g), g, f)
-                                         for g, f in mainforms.iteritems()):
+                                         for g, f in mainforms.items()):
             self.wrap_main_form(group, label, form)
         for label, group, objects in sorted((_(g), g, o)
-                                            for g, o in groupedforms.iteritems()):
+                                            for g, o in groupedforms.items()):
             self.wrap_grouped_form(group, label, objects)
 
     @property
@@ -171,7 +171,7 @@
             entity = self.cwprops_rset.get_entity(values[key], 0)
         else:
             entity = self._cw.vreg['etypes'].etype_class('CWProperty')(self._cw)
-            entity.eid = self._cw.varmaker.next()
+            entity.eid = next(self._cw.varmaker)
             entity.cw_attr_cache['pkey'] = key
             entity.cw_attr_cache['value'] = self._cw.vreg.property_value(key)
         return entity
@@ -224,7 +224,7 @@
           (make_togglable_link('fieldset_' + group, label)))
         self.w(u'<div id="fieldset_%s" %s>' % (group, status))
         sorted_objects = sorted((self._cw.__('%s_%s' % (group, o)), o, f)
-                                for o, f in objects.iteritems())
+                                for o, f in objects.items())
         for label, oid, form in sorted_objects:
             self.wrap_object_form(group, oid, label, form)
         self.w(u'</div>')
--- a/web/views/cwsources.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/cwsources.py	Thu Dec 10 12:34:15 2015 +0100
@@ -20,20 +20,23 @@
 """
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 import logging
 from itertools import repeat
+
+from six.moves import range
+
 from logilab.mtconverter import xml_escape
 from logilab.common.decorators import cachedproperty
 
 from cubicweb import Unauthorized, tags
 from cubicweb.utils import make_uid
 from cubicweb.predicates import (is_instance, score_entity, has_related_entities,
-                                match_user_groups, match_kwargs, match_view)
+                                 match_user_groups, match_kwargs, match_view, one_line_rset)
 from cubicweb.view import EntityView, StartupView
 from cubicweb.schema import META_RTYPES, VIRTUAL_RTYPES, display_name
-from cubicweb.web import formwidgets as wdgs, facet
+from cubicweb.web import Redirect, formwidgets as wdgs, facet, action
 from cubicweb.web.views import add_etype_button
 from cubicweb.web.views import (uicfg, tabs, actions, ibreadcrumbs, navigation,
                                 tableview, pyviews)
@@ -95,7 +98,7 @@
             if hostconfig:
                 self.w(u'<h3>%s</h3>' % self._cw._('CWSourceHostConfig_plural'))
                 self._cw.view('table', hostconfig, w=self.w,
-                              displaycols=range(2),
+                              displaycols=list(range(2)),
                               cellvids={1: 'editable-final'})
 
 
@@ -186,7 +189,7 @@
                     warning(_('relation %(rtype)s with %(etype)s as %(role)s is '
                               'supported but no target type supported') %
                             {'rtype': rschema, 'role': role, 'etype': etype})
-        for rtype, rdefs in self.srelations.iteritems():
+        for rtype, rdefs in self.srelations.items():
             if rdefs is None:
                 rschema = self.schema[rtype]
                 for subj, obj in rschema.rdefs:
@@ -223,6 +226,36 @@
     layout_args = {'display_filter': 'top'}
 
 
+class CWSourceSyncAction(action.Action):
+    __regid__ = 'cw.source-sync'
+    __select__ = (action.Action.__select__ & match_user_groups('managers')
+                  & one_line_rset() & is_instance('CWSource')
+                  & score_entity(lambda x: x.name != 'system'))
+
+    title = _('synchronize')
+    category = 'mainactions'
+    order = 20
+
+    def url(self):
+        entity = self.cw_rset.get_entity(self.cw_row or 0, self.cw_col or 0)
+        return entity.absolute_url(vid=self.__regid__)
+
+
+class CWSourceSyncView(EntityView):
+    __regid__ = 'cw.source-sync'
+    __select__ = (match_user_groups('managers')
+                  & one_line_rset() & is_instance('CWSource')
+                  & score_entity(lambda x: x.name != 'system'))
+
+    title = _('synchronize')
+
+    def entity_call(self, entity):
+        self._cw.call_service('source-sync', source_eid=entity.eid)
+        msg = self._cw._('Source has been synchronized')
+        url = entity.absolute_url(tab='cwsource-imports', __message=msg)
+        raise Redirect(url)
+
+
 
 
 # sources management view ######################################################
--- a/web/views/cwuser.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/cwuser.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,10 +18,13 @@
 """Specific views for users and groups"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from hashlib import sha1 # pylint: disable=E0611
 
+from six import text_type
+from six.moves import range
+
 from logilab.mtconverter import xml_escape
 
 from cubicweb import tags
@@ -64,7 +67,7 @@
 <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
          xmlns:rdfs="http://www.w3org/2000/01/rdf-schema#"
          xmlns:foaf="http://xmlns.com/foaf/0.1/"> '''% self._cw.encoding)
-        for i in xrange(self.cw_rset.rowcount):
+        for i in range(self.cw_rset.rowcount):
             self.cell_call(i, 0)
         self.w(u'</rdf:RDF>\n')
 
@@ -250,6 +253,6 @@
         'group': tableview.MainEntityColRenderer(),
         'nb_users': tableview.EntityTableColRenderer(
             header=_('num. users'),
-            renderfunc=lambda w,x: w(unicode(x.num_users())),
+            renderfunc=lambda w,x: w(text_type(x.num_users())),
             sortfunc=lambda x: x.num_users()),
         }
--- a/web/views/debug.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/debug.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,10 +18,12 @@
 """management and error screens"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from time import strftime, localtime
 
+from six import text_type
+
 from logilab.mtconverter import xml_escape
 
 from cubicweb.predicates import none_rset, match_user_groups
@@ -33,7 +35,7 @@
     if dict:
         w(u'<ul>')
         for key in sorted(dict):
-            w(u'<li><span class="label">%s</span>: <span>%s</span></li>' % (
+            w(u'<li><span>%s</span>: <span>%s</span></li>' % (
                 xml_escape(str(key)), xml_escape(repr(dict[key]))))
         w(u'</ul>')
 
@@ -71,31 +73,23 @@
         dtformat = req.property_value('ui.datetime-format')
         _ = req._
         w = self.w
+        repo = req.cnx.repo
         # generic instance information
         w(u'<h2>%s</h2>' % _('Instance'))
-        w(u'<table>')
-        w(u'<tr><th align="left">%s</th><td>%s</td></tr>' % (
-            _('config type'), self._cw.vreg.config.name))
-        w(u'<tr><th align="left">%s</th><td>%s</td></tr>' % (
-            _('config mode'), self._cw.vreg.config.mode))
-        w(u'<tr><th align="left">%s</th><td>%s</td></tr>' % (
-            _('instance home'), self._cw.vreg.config.apphome))
-        w(u'</table>')
-        vcconf = req.vreg.config.vc_config()
+        pyvalue = ((_('config type'), self._cw.vreg.config.name),
+                   (_('config mode'), self._cw.vreg.config.mode),
+                   (_('instance home'), self._cw.vreg.config.apphome))
+        self.wview('pyvaltable', pyvalue=pyvalue, header_column_idx=0)
+        vcconf = repo.get_versions()
         w(u'<h3>%s</h3>' % _('versions configuration'))
-        w(u'<table>')
-        w(u'<tr><th align="left">%s</th><td>%s</td></tr>' % (
-            'CubicWeb', vcconf.get('cubicweb', _('no version information'))))
-        for cube in sorted(self._cw.vreg.config.cubes()):
-            cubeversion = vcconf.get(cube, _('no version information'))
-            w(u'<tr><th align="left">%s</th><td>%s</td></tr>' % (
-                cube, cubeversion))
-        w(u'</table>')
+        missing = _('no version information')
+        pyvalue = [('CubicWeb', vcconf.get('cubicweb', missing))]
+        pyvalue += [(cube, vcconf.get(cube, missing))
+                    for cube in sorted(self._cw.vreg.config.cubes())]
+        self.wview('pyvaltable', pyvalue=pyvalue, header_column_idx=0)
         # repository information
-        repo = req.vreg.config.repository(None)
         w(u'<h2>%s</h2>' % _('Repository'))
         w(u'<h3>%s</h3>' % _('resources usage'))
-        w(u'<table>')
         stats = self._cw.call_service('repo_stats')
         stats['looping_tasks'] = ', '.join('%s (%s seconds)' % (n, i) for n, i in stats['looping_tasks'])
         stats['threads'] = ', '.join(sorted(stats['threads']))
@@ -104,11 +98,13 @@
                 continue
             if k.endswith('_cache_size'):
                 stats[k] = '%s / %s' % (stats[k]['size'], stats[k]['maxsize'])
-        for element in sorted(stats):
-            w(u'<tr><th align="left">%s</th><td>%s %s</td></tr>'
-                   % (element, xml_escape(unicode(stats[element])),
-                      element.endswith('percent') and '%' or '' ))
-        w(u'</table>')
+        def format_stat(sname, sval):
+            return '%s %s' % (xml_escape(text_type(sval)),
+                              sname.endswith('percent') and '%' or '')
+        pyvalue = [(sname, format_stat(sname, sval))
+                    for sname, sval in sorted(stats.items())]
+        self.wview('pyvaltable', pyvalue=pyvalue, header_column_idx=0)
+        # open repo sessions
         if req.cnx.is_repo_in_memory and req.user.is_in_group('managers'):
             w(u'<h3>%s</h3>' % _('opened sessions'))
             sessions = repo._sessions.values()
@@ -116,7 +112,7 @@
                 w(u'<ul>')
                 for session in sessions:
                     w(u'<li>%s (%s: %s)<br/>' % (
-                        xml_escape(unicode(session)),
+                        xml_escape(text_type(session)),
                         _('last usage'),
                         strftime(dtformat, localtime(session.timestamp))))
                     dict_to_html(w, session.data)
@@ -126,12 +122,9 @@
                 w(u'<p>%s</p>' % _('no repository sessions found'))
         # web server information
         w(u'<h2>%s</h2>' % _('Web server'))
-        w(u'<table>')
-        w(u'<tr><th align="left">%s</th><td>%s</td></tr>' % (
-            _('base url'), req.base_url()))
-        w(u'<tr><th align="left">%s</th><td>%s</td></tr>' % (
-            _('data directory url'), req.datadir_url))
-        w(u'</table>')
+        pyvalue = ((_('base url'), req.base_url()),
+                   (_('data directory url'), req.datadir_url))
+        self.wview('pyvaltable', pyvalue=pyvalue, header_column_idx=0)
         from cubicweb.web.application import SESSION_MANAGER
         if SESSION_MANAGER is not None and req.user.is_in_group('managers'):
             sessions = SESSION_MANAGER.current_sessions()
@@ -170,7 +163,7 @@
                 continue
             self.w(u'<h3 id="%s">%s</h3>' % (key, key))
             if self._cw.vreg[key]:
-                values = sorted(self._cw.vreg[key].iteritems())
+                values = sorted(self._cw.vreg[key].items())
                 self.wview('pyvaltable', pyvalue=[(key, xml_escape(repr(val)))
                                                   for key, val in values])
             else:
--- a/web/views/dotgraphview.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/dotgraphview.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,7 +18,7 @@
 """some basic stuff to build dot generated graph images"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 import tempfile
 import os
--- a/web/views/editcontroller.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/editcontroller.py	Thu Dec 10 12:34:15 2015 +0100
@@ -24,6 +24,8 @@
 
 from datetime import datetime
 
+from six import text_type
+
 from logilab.common.deprecation import deprecated
 from logilab.common.graph import ordered_nodes
 
@@ -93,9 +95,9 @@
 
     def update_query(self, eid):
         varmaker = rqlvar_maker()
-        var = varmaker.next()
+        var = next(varmaker)
         while var in self.kwargs:
-            var = varmaker.next()
+            var = next(varmaker)
         rql = 'SET %s WHERE X eid %%(%s)s' % (','.join(self.edited), var)
         if self.restrictions:
             rql += ', %s' % ','.join(self.restrictions)
@@ -143,7 +145,7 @@
         values_by_eid = dict((eid, req.extract_entity_params(eid, minparams=2))
                              for eid in req.edited_eids())
         # iterate over all the edited entities
-        for eid, values in values_by_eid.iteritems():
+        for eid, values in values_by_eid.items():
             # add eid to the dependency graph
             graph.setdefault(eid, set())
             # search entity's edited fields for mandatory inlined relation
@@ -197,7 +199,7 @@
             if '__linkto' in req.form and 'eid' in req.form:
                 self.execute_linkto()
             elif not ('__delete' in req.form or '__insert' in req.form):
-                raise ValidationError(None, {None: unicode(ex)})
+                raise ValidationError(None, {None: text_type(ex)})
         # all pending inlined relations to newly created entities have been
         # treated now (pop to ensure there are no attempt to add new ones)
         pending_inlined = req.data.pop('pending_inlined')
@@ -215,7 +217,7 @@
                 autoform.delete_relations(self._cw, todelete)
         self._cw.remove_pending_operations()
         if self.errors:
-            errors = dict((f.name, unicode(ex)) for f, ex in self.errors)
+            errors = dict((f.name, text_type(ex)) for f, ex in self.errors)
             raise ValidationError(valerror_eid(form.get('__maineid')), errors)
 
     def _insert_entity(self, etype, eid, rqlquery):
@@ -265,7 +267,7 @@
         for form_, field in req.data['pending_inlined'].pop(entity.eid, ()):
             rqlquery.set_inlined(field.name, form_.edited_entity.eid)
         if self.errors:
-            errors = dict((f.role_name(), unicode(ex)) for f, ex in self.errors)
+            errors = dict((f.role_name(), text_type(ex)) for f, ex in self.errors)
             raise ValidationError(valerror_eid(entity.eid), errors)
         if eid is None: # creation or copy
             entity.eid = eid = self._insert_entity(etype, formparams['eid'], rqlquery)
@@ -316,7 +318,7 @@
         """handle edition for the (rschema, x) relation of the given entity
         """
         if values:
-            rqlquery.set_inlined(field.name, iter(values).next())
+            rqlquery.set_inlined(field.name, next(iter(values)))
         elif form.edited_entity.has_eid():
             self.handle_relation(form, field, values, origvalues)
 
@@ -355,13 +357,13 @@
         for eid, etype in eidtypes:
             entity = self._cw.entity_from_eid(eid, etype)
             path, params = entity.cw_adapt_to('IEditControl').after_deletion_path()
-            redirect_info.add( (path, tuple(params.iteritems())) )
+            redirect_info.add( (path, tuple(params.items())) )
             entity.cw_delete()
         if len(redirect_info) > 1:
             # In the face of ambiguity, refuse the temptation to guess.
             self._after_deletion_path = 'view', ()
         else:
-            self._after_deletion_path = iter(redirect_info).next()
+            self._after_deletion_path = next(iter(redirect_info))
         if len(eidtypes) > 1:
             self._cw.set_message(self._cw._('entities deleted'))
         else:
@@ -388,13 +390,6 @@
         self._default_publish()
         self.reset()
 
-    def _action_cancel(self):
-        errorurl = self._cw.form.get('__errorurl')
-        if errorurl:
-            self._cw.cancel_edition(errorurl)
-        self._cw.set_message(self._cw._('edit canceled'))
-        return self.reset()
-
     def _action_delete(self):
         self.delete_entities(self._cw.edited_eids(withtype=True))
         return self.reset()
--- a/web/views/editforms.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/editforms.py	Thu Dec 10 12:34:15 2015 +0100
@@ -20,10 +20,12 @@
 """
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from copy import copy
 
+from six.moves import range
+
 from logilab.mtconverter import xml_escape
 from logilab.common.decorators import cached
 from logilab.common.registry import yes
@@ -145,7 +147,7 @@
         # selector
         etype = kwargs.pop('etype', self._cw.form.get('etype'))
         entity = self._cw.vreg['etypes'].etype_class(etype)(self._cw)
-        entity.eid = self._cw.varmaker.next()
+        entity.eid = next(self._cw.varmaker)
         self.render_form(entity)
 
     def form_title(self, entity):
@@ -197,7 +199,7 @@
         entity.complete()
         self.newentity = copy(entity)
         self.copying = entity
-        self.newentity.eid = self._cw.varmaker.next()
+        self.newentity.eid = next(self._cw.varmaker)
         self.w(u'<script type="text/javascript">updateMessage("%s");</script>\n'
                % self._cw._(self.warning_message))
         super(CopyFormView, self).render_form(self.newentity)
@@ -230,7 +232,7 @@
     def __init__(self, req, rset, **kwargs):
         kwargs.setdefault('__redirectrql', rset.printable_rql())
         super(TableEditForm, self).__init__(req, rset=rset, **kwargs)
-        for row in xrange(len(self.cw_rset)):
+        for row in range(len(self.cw_rset)):
             form = self._cw.vreg['forms'].select('edition', self._cw,
                                                  rset=self.cw_rset, row=row,
                                                  formtype='muledit',
--- a/web/views/editviews.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/editviews.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,7 +18,7 @@
 """Some views used to help to the edition process"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from logilab.common.decorators import cached
 from logilab.mtconverter import xml_escape
--- a/web/views/facets.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/facets.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,7 +18,7 @@
 """the facets box and some basic facets"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from warnings import warn
 
@@ -168,7 +168,7 @@
                  DeprecationWarning, stacklevel=2)
         else:
             vidargs = {}
-        vidargs = dict((k, v) for k, v in vidargs.iteritems() if v)
+        vidargs = dict((k, v) for k, v in vidargs.items() if v)
         facetargs = xml_escape(json_dumps([divid, vid, paginate, vidargs]))
         w(u'<form id="%sForm" class="%s" method="post" action="" '
           'cubicweb:facetargs="%s" >' % (divid, cssclass, facetargs))
--- a/web/views/formrenderers.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/formrenderers.py	Thu Dec 10 12:34:15 2015 +0100
@@ -33,10 +33,12 @@
 """
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from warnings import warn
 
+from six import text_type
+
 from logilab.mtconverter import xml_escape
 from logilab.common.registry import yes
 
@@ -119,7 +121,7 @@
             data.insert(0, errormsg)
         # NOTE: we call unicode because `tag` objects may be found within data
         #       e.g. from the cwtags library
-        w(''.join(unicode(x) for x in data))
+        w(''.join(text_type(x) for x in data))
 
     def render_content(self, w, form, values):
         if self.display_progress_div:
@@ -241,7 +243,7 @@
         if form.fieldsets_in_order:
             fieldsets = form.fieldsets_in_order
         else:
-            fieldsets = byfieldset.iterkeys()
+            fieldsets = byfieldset
         for fieldset in list(fieldsets):
             try:
                 fields = byfieldset.pop(fieldset)
@@ -542,4 +544,3 @@
             self._render_fields(fields, w, form)
         self.render_child_forms(w, form, values)
         w(u'</fieldset>')
-
--- a/web/views/forms.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/forms.py	Thu Dec 10 12:34:15 2015 +0100
@@ -48,6 +48,9 @@
 from warnings import warn
 
 import time
+import inspect
+
+from six import text_type
 
 from logilab.common import dictattr, tempattr
 from logilab.common.decorators import iclassmethod, cached
@@ -257,7 +260,7 @@
                 editedfields = self._cw.form['_cw_fields']
             except KeyError:
                 raise RequestError(self._cw._('no edited fields specified'))
-        entityform = entity and self.field_by_name.im_func.func_code.co_argcount == 4 # XXX
+        entityform = entity and len(inspect.getargspec(self.field_by_name)) == 4 # XXX
         for editedfield in splitstrip(editedfields):
             try:
                 name, role = editedfield.split('-')
@@ -286,7 +289,7 @@
                 except ProcessFormError as exc:
                     errors.append((field, exc))
             if errors:
-                errors = dict((f.role_name(), unicode(ex)) for f, ex in errors)
+                errors = dict((f.role_name(), text_type(ex)) for f, ex in errors)
                 raise ValidationError(None, errors)
             return processed
 
@@ -377,7 +380,7 @@
 
         Warning: this method must be called only when all form fields are setup
         """
-        for (rtype, role), eids in self.linked_to.iteritems():
+        for (rtype, role), eids in self.linked_to.items():
             # if the relation is already setup by a form field, do not add it
             # in a __linkto hidden to avoid setting it twice in the controller
             try:
--- a/web/views/ibreadcrumbs.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/ibreadcrumbs.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,10 +18,12 @@
 """breadcrumbs components definition for CubicWeb web client"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from warnings import warn
 
+from six import text_type
+
 from logilab.mtconverter import xml_escape
 
 from cubicweb import tags, uilib
@@ -141,7 +143,7 @@
                 xml_escape(url), xml_escape(uilib.cut(title, textsize))))
         else:
             textsize = self._cw.property_value('navigation.short-line-size')
-            w(xml_escape(uilib.cut(unicode(part), textsize)))
+            w(xml_escape(uilib.cut(text_type(part), textsize)))
 
 
 class BreadCrumbETypeVComponent(BreadCrumbEntityVComponent):
--- a/web/views/idownloadable.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/idownloadable.py	Thu Dec 10 12:34:15 2015 +0100
@@ -20,7 +20,9 @@
 =====================================================
 """
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
+
+from six.moves import range
 
 from logilab.mtconverter import BINARY_ENCODINGS, TransformError, xml_escape
 from logilab.common.deprecation import class_renamed, deprecated
@@ -166,7 +168,7 @@
 
     def call(self, **kwargs):
         rset = self.cw_rset
-        for i in xrange(len(rset)):
+        for i in range(len(rset)):
             self.w(u'<div class="efile">')
             self.wview(self.__regid__, rset, row=i, col=0, **kwargs)
             self.w(u'</div>')
@@ -199,6 +201,3 @@
 
     title = _('embedded html')
     _embedding_tag = tags.iframe
-
-
-
--- a/web/views/json.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/json.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,7 +18,7 @@
 """json export views"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from cubicweb.uilib import rest_traceback
 
@@ -64,7 +64,7 @@
             # use ``application/javascript`` if ``callback`` parameter is
             # provided, keep ``application/json`` otherwise
             self._cw.set_content_type('application/javascript')
-            json_data = b'%s(%s)' % (json_padding, json_data)
+            json_data = json_padding + b'(' + json_data + b')'
         return json_data
 
 
@@ -85,7 +85,8 @@
             indent = int(self._cw.form['_indent'])
         else:
             indent = None
-        self.w(json_dumps(data, indent=indent))
+        # python's json.dumps escapes non-ascii characters
+        self.w(json_dumps(data, indent=indent).encode('ascii'))
 
 
 class JsonRsetView(JsonMixIn, AnyRsetView):
--- a/web/views/magicsearch.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/magicsearch.py	Thu Dec 10 12:34:15 2015 +0100
@@ -23,6 +23,8 @@
 import re
 from logging import getLogger
 
+from six import text_type
+
 from yams.interfaces import IVocabularyConstraint
 
 from rql import RQLSyntaxError, BadRQLQuery, parse
@@ -86,7 +88,7 @@
             else:
                 # Only one possible translation, no ambiguity
                 if len(translation_set) == 1:
-                    relation.r_type = iter(translations[rtype]).next()
+                    relation.r_type = next(iter(translations[rtype]))
                 # More than 1 possible translation => resolve it later
                 else:
                     ambiguous_nodes[relation] = (lhs.name, translation_set)
@@ -386,7 +388,7 @@
         self.processors = sorted(processors, key=lambda x: x.priority)
 
     def process_query(self, uquery):
-        assert isinstance(uquery, unicode)
+        assert isinstance(uquery, text_type)
         try:
             procname, query = uquery.split(':', 1)
             proc = self.by_name[procname.strip().lower()]
@@ -589,7 +591,7 @@
         """
         schema = self._cw.vreg.schema
         relations = set()
-        untyped_dest_var = rqlvar_maker(defined=select.defined_vars).next()
+        untyped_dest_var = next(rqlvar_maker(defined=select.defined_vars))
         # for each solution
         # 1. find each possible relation
         # 2. for each relation:
@@ -643,7 +645,7 @@
                 vocab_kwargs = {}
                 if rtype_incomplete_value:
                     vocab_rql += ', X %s LIKE %%(value)s' % user_rtype
-                    vocab_kwargs['value'] = '%s%%' % rtype_incomplete_value
+                    vocab_kwargs['value'] = u'%s%%' % rtype_incomplete_value
                 vocab += [value for value, in
                           self._cw.execute(vocab_rql, vocab_kwargs)]
         return sorted(set(vocab))
--- a/web/views/management.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/management.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,7 +18,7 @@
 """security management and error screens"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 
 from logilab.mtconverter import xml_escape
@@ -137,7 +137,7 @@
         # if excinfo is not None, it's probably not a bug
         if excinfo is None:
             return
-        vcconf = self._cw.vreg.config.vc_config()
+        vcconf = self._cw.cnx.repo.get_versions()
         w(u"<div>")
         eversion = vcconf.get('cubicweb', self._cw._('no version information'))
         # NOTE: tuple wrapping needed since eversion is itself a tuple
@@ -169,7 +169,7 @@
     binfo += u'\n\n:URL: %s\n' % req.url()
     if not '__bugreporting' in req.form:
         binfo += u'\n:form params:\n'
-        binfo += u'\n'.join(u'  * %s = %s' % (k, v) for k, v in req.form.iteritems())
+        binfo += u'\n'.join(u'  * %s = %s' % (k, v) for k, v in req.form.items())
     binfo += u'\n\n:CubicWeb version: %s\n'  % (eversion,)
     for pkg, pkgversion in cubes:
         binfo += u":Cube %s version: %s\n" % (pkg, pkgversion)
--- a/web/views/navigation.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/navigation.py	Thu Dec 10 12:34:15 2015 +0100
@@ -46,10 +46,12 @@
 """
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from datetime import datetime
 
+from six import text_type
+
 from rql.nodes import VariableRef, Constant
 
 from logilab.mtconverter import xml_escape
@@ -192,10 +194,10 @@
                 return entity.printable_value(attrname, format='text/plain')
         elif col is None: # smart links disabled.
             def index_display(row):
-                return unicode(row)
+                return text_type(row)
         elif self._cw.vreg.schema.eschema(rset.description[0][col]).final:
             def index_display(row):
-                return unicode(rset[row][col])
+                return text_type(rset[row][col])
         else:
             def index_display(row):
                 return rset.get_entity(row, col).view('text')
--- a/web/views/owl.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/owl.py	Thu Dec 10 12:34:15 2015 +0100
@@ -19,7 +19,9 @@
 
 """
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
+
+from six.moves import range
 
 from logilab.mtconverter import TransformError, xml_escape
 
@@ -166,7 +168,7 @@
 
     def call(self):
         self.w(OWL_OPENING_ROOT % {'appid': self._cw.vreg.schema.name})
-        for i in xrange(self.cw_rset.rowcount):
+        for i in range(self.cw_rset.rowcount):
             self.cell_call(i, 0)
         self.w(OWL_CLOSING_ROOT)
 
--- a/web/views/plots.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/plots.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,7 +18,10 @@
 """basic plot views"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
+
+from six import add_metaclass
+from six.moves import range
 
 from logilab.common.date import datetime2ticks
 from logilab.common.deprecation import class_deprecated
@@ -83,9 +86,10 @@
     def _render(self, *args, **kwargs):
         raise NotImplementedError
 
+
+@add_metaclass(class_deprecated)
 class FlotPlotWidget(PlotWidget):
     """PlotRenderer widget using Flot"""
-    __metaclass__ = class_deprecated
     __deprecation_warning__ = '[3.14] cubicweb.web.views.plots module is deprecated, use the jqplot cube instead'
     onload = u"""
 var fig = jQuery('#%(figid)s');
@@ -117,7 +121,7 @@
         if req.ie_browser():
             req.add_js('excanvas.js')
         req.add_js(('jquery.flot.js', 'cubicweb.flot.js'))
-        figid = u'figure%s' % req.varmaker.next()
+        figid = u'figure%s' % next(req.varmaker)
         plotdefs = []
         plotdata = []
         self.w(u'<div id="%s" style="width: %spx; height: %spx;"></div>' %
@@ -137,8 +141,8 @@
                                      'dateformat': '"%s"' % fmt})
 
 
+@add_metaclass(class_deprecated)
 class PlotView(baseviews.AnyRsetView):
-    __metaclass__ = class_deprecated
     __deprecation_warning__ = '[3.14] cubicweb.web.views.plots module is deprecated, use the jqplot cube instead'
     __regid__ = 'plot'
     title = _('generic plot')
@@ -154,7 +158,7 @@
         abscissa = [row[0] for row in self.cw_rset]
         plots = []
         nbcols = len(self.cw_rset.rows[0])
-        for col in xrange(1, nbcols):
+        for col in range(1, nbcols):
             data = [row[col] for row in self.cw_rset]
             plots.append(filterout_nulls(abscissa, data))
         plotwidget = FlotPlotWidget(varnames, plots, timemode=self.timemode)
--- a/web/views/primary.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/primary.py	Thu Dec 10 12:34:15 2015 +0100
@@ -38,7 +38,7 @@
 """
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from warnings import warn
 
--- a/web/views/pyviews.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/pyviews.py	Thu Dec 10 12:34:15 2015 +0100
@@ -19,6 +19,9 @@
 """
 __docformat__ = "restructuredtext en"
 
+from six import text_type
+from six.moves import range
+
 from cubicweb.view import View
 from cubicweb.predicates import match_kwargs
 from cubicweb.web.views import tableview
@@ -38,7 +41,7 @@
             w(self.empty_cell_content)
 
     def render_cell(self, w, rownum):
-        w(unicode(self.data[rownum][self.colid]))
+        w(text_type(self.data[rownum][self.colid]))
 
 
 class PyValTableView(tableview.TableMixIn, View):
@@ -100,7 +103,7 @@
 
     def build_column_renderers(self):
         return [self.column_renderer(colid)
-                for colid in xrange(len(self.pyvalue[0]))]
+                for colid in range(len(self.pyvalue[0]))]
 
     def facets_form(self, mainvar=None):
         return None # not supported
--- a/web/views/rdf.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/rdf.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,7 +18,9 @@
 """base xml and rss views"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
+
+from six.moves import range
 
 from yams import xy
 
@@ -56,7 +58,7 @@
             graph.bind('cw', CW)
             for prefix, xmlns in xy.XY.prefixes.items():
                 graph.bind(prefix, rdflib.Namespace(xmlns))
-            for i in xrange(self.cw_rset.rowcount):
+            for i in range(self.cw_rset.rowcount):
                 entity = self.cw_rset.complete_entity(i, 0)
                 self.entity2graph(graph, entity)
             self.w(graph.serialize(format=self.format))
--- a/web/views/reledit.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/reledit.py	Thu Dec 10 12:34:15 2015 +0100
@@ -20,7 +20,7 @@
 """
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 import copy
 from warnings import warn
@@ -259,7 +259,7 @@
         elif action == 'add':
             add_etype = self._compute_ttypes(rschema, role)[0]
             _new_entity = self._cw.vreg['etypes'].etype_class(add_etype)(self._cw)
-            _new_entity.eid = self._cw.varmaker.next()
+            _new_entity.eid = next(self._cw.varmaker)
             edit_entity = _new_entity
             # XXX see forms.py ~ 276 and entities.linked_to method
             #     is there another way?
@@ -292,7 +292,7 @@
             cwtarget='eformframe', cssclass='releditForm',
             **formargs)
         # pass reledit arguments
-        for pname, pvalue in event_args.iteritems():
+        for pname, pvalue in event_args.items():
             form.add_hidden('__reledit|' + pname, pvalue)
         # handle buttons
         if form.form_buttons: # edition, delete
@@ -402,4 +402,3 @@
         assert args['reload'].startswith('http')
     view = req.vreg['views'].select('reledit', req, rset=rset, rtype=args['rtype'])
     return self._call_view(view, **args)
-
--- a/web/views/schema.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/schema.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,7 +18,7 @@
 """Specific views for schema related entities"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from itertools import cycle
 
@@ -26,6 +26,8 @@
 import os, os.path as osp
 import codecs
 
+from six import text_type
+
 from logilab.common.graph import GraphGenerator, DotBackend
 from logilab.common.ureports import Section, Table
 from logilab.common.registry import yes
@@ -114,7 +116,7 @@
     def grouped_permissions_table(self, rschema):
         # group relation definitions with identical permissions
         perms = {}
-        for rdef in rschema.rdefs.itervalues():
+        for rdef in rschema.rdefs.values():
             rdef_perms = []
             for action in rdef.ACTIONS:
                 groups = sorted(rdef.get_groups(action))
@@ -131,7 +133,7 @@
         _ = self._cw._
         w(u'<div style="margin: 0px 1.5em">')
         tmpl = u'<strong>%s</strong> %s <strong>%s</strong>'
-        for perm, rdefs in perms.iteritems():
+        for perm, rdefs in perms.items():
             w(u'<div>%s</div>' % u', '.join(
                 tmpl % (_(s.type), _(rschema.type), _(o.type)) for s, o in rdefs))
             # accessing rdef from previous loop by design: only used to get
@@ -279,7 +281,7 @@
     def cell_call(self, row, col):
         defaultval = self.cw_rset.rows[row][col]
         if defaultval is not None:
-            self.w(unicode(self.cw_rset.rows[row][col].unzpickle()))
+            self.w(text_type(self.cw_rset.rows[row][col].unzpickle()))
 
 class CWETypeRelationCardinalityCell(baseviews.FinalView):
     __regid__ = 'etype-rel-cardinality-cell'
@@ -487,7 +489,7 @@
         entity = self.cw_rset.get_entity(row, col)
         rschema = self._cw.vreg.schema.rschema(entity.rtype.name)
         rdef = rschema.rdefs[(entity.stype.name, entity.otype.name)]
-        constraints = [xml_escape(unicode(c)) for c in getattr(rdef, 'constraints')]
+        constraints = [xml_escape(text_type(c)) for c in getattr(rdef, 'constraints')]
         self.w(u'<br/>'.join(constraints))
 
 class CWAttributeOptionsCell(EntityView):
@@ -557,8 +559,9 @@
     def __init__(self, visitor, cw):
         self.visitor = visitor
         self.cw = cw
-        self.nextcolor = cycle( ('#ff7700', '#000000',
-                                 '#ebbc69', '#888888') ).next
+        self._cycle = iter(cycle(('#ff7700', '#000000', '#ebbc69', '#888888')))
+        self.nextcolor = lambda: next(self._cycle)
+
         self.colors = {}
 
     def node_properties(self, eschema):
--- a/web/views/sessions.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/sessions.py	Thu Dec 10 12:34:15 2015 +0100
@@ -19,20 +19,28 @@
 __docformat__ = "restructuredtext en"
 
 from time import time
+from logging import getLogger
 
-from cubicweb import RepositoryError, Unauthorized, BadConnectionId
-from cubicweb.web import InvalidSession, component
+from logilab.common.registry import RegistrableObject
+
+from cubicweb import RepositoryError, Unauthorized, BadConnectionId, set_log_methods
+from cubicweb.predicates import yes
+from cubicweb.web import InvalidSession
+
+from cubicweb.web.views import authentication
 
 
-class AbstractSessionManager(component.Component):
+class AbstractSessionManager(RegistrableObject):
     """manage session data associated to a session identifier"""
     __abstract__ = True
+    __select__ = yes()
+    __registry__ = 'sessions'
     __regid__ = 'sessionmanager'
 
     def __init__(self, repo):
         vreg = repo.vreg
         self.session_time = vreg.config['http-session-time'] or None
-        self.authmanager = vreg['components'].select('authmanager', repo=repo)
+        self.authmanager = authentication.RepositoryAuthenticationManager(repo)
         interval = (self.session_time or 0) / 2.
         if vreg.config.anonymous_user()[0] is not None:
             self.cleanup_anon_session_time = vreg.config['cleanup-anonymous-session-time'] or 5 * 60
@@ -53,15 +61,7 @@
         closed, total = 0, 0
         for session in self.current_sessions():
             total += 1
-            try:
-                last_usage_time = session.cnx.check()
-            except AttributeError:
-                last_usage_time = session.mtime
-            except BadConnectionId:
-                self.close_session(session)
-                closed += 1
-                continue
-
+            last_usage_time = session.mtime
             no_use_time = (time() - last_usage_time)
             if session.anonymous_session:
                 if no_use_time >= self.cleanup_anon_session_time:
@@ -95,11 +95,14 @@
         raise NotImplementedError()
 
 
+set_log_methods(AbstractSessionManager, getLogger('cubicweb.sessionmanager'))
+
+
 class InMemoryRepositorySessionManager(AbstractSessionManager):
     """manage session data associated to a session identifier"""
 
     def __init__(self, *args, **kwargs):
-        AbstractSessionManager.__init__(self, *args, **kwargs)
+        super(InMemoryRepositorySessionManager, self).__init__(*args, **kwargs)
         # XXX require a RepositoryAuthenticationManager which violates
         #     authenticate interface by returning a session instead of a user
         #assert isinstance(self.authmanager, RepositoryAuthenticationManager)
--- a/web/views/sparql.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/sparql.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,7 +18,9 @@
 """SPARQL integration"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
+
+from six.moves import range
 
 from yams import xy
 from rql import TypeResolverException
@@ -111,7 +113,7 @@
         rqlst = self.cw_rset.syntax_tree().children[0]
         varnames = [var.name for var in rqlst.selection]
         results = E.results()
-        for rowidx in xrange(len(self.cw_rset)):
+        for rowidx in range(len(self.cw_rset)):
             result = E.result()
             for colidx, varname in enumerate(varnames):
                 result.append(self.cell_binding(rowidx, colidx, varname))
@@ -140,4 +142,4 @@
 
 def registration_callback(vreg):
     if Sparql2rqlTranslator is not None:
-        vreg.register_all(globals().itervalues(), __name__)
+        vreg.register_all(globals().values(), __name__)
--- a/web/views/startup.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/startup.py	Thu Dec 10 12:34:15 2015 +0100
@@ -22,7 +22,7 @@
 """
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from logilab.common.textutils import unormalize
 from logilab.common.deprecation import deprecated
@@ -106,7 +106,7 @@
 
     def entity_types_table(self, eschemas):
         infos = sorted(self.entity_types(eschemas),
-                       key=lambda (l,a,e): unormalize(l))
+                       key=lambda t: unormalize(t[0]))
         q, r = divmod(len(infos), 2)
         if r:
             infos.append( (None, '&#160;', '&#160;') )
@@ -172,4 +172,3 @@
     @deprecated('[3.11] display_folders method is deprecated, backport it if needed')
     def display_folders(self):
         return 'Folder' in self._cw.vreg.schema and self._cw.execute('Any COUNT(X) WHERE X is Folder')[0][0]
-
--- a/web/views/staticcontrollers.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/staticcontrollers.py	Thu Dec 10 12:34:15 2015 +0100
@@ -33,7 +33,7 @@
 from logging import getLogger
 
 from cubicweb import Forbidden
-from cubicweb.web import NotFound
+from cubicweb.web import NotFound, Redirect
 from cubicweb.web.http_headers import generateDateTime
 from cubicweb.web.controller import Controller
 from cubicweb.web.views.urlrewrite import URLRewriter
@@ -66,9 +66,10 @@
         if not debugmode:
             # XXX: Don't provide additional resource information to error responses
             #
-            # the HTTP RFC recommands not going further than 1 year ahead
-            expires = datetime.now() + timedelta(days=6*30)
+            # the HTTP RFC recommends not going further than 1 year ahead
+            expires = datetime.now() + timedelta(seconds=self.max_age(path))
             self._cw.set_header('Expires', generateDateTime(mktime(expires.timetuple())))
+            self._cw.set_header('Cache-Control', 'max-age=%s' % self.max_age(path))
 
         # XXX system call to os.stats could be cached once and for all in
         # production mode (where static files are not expected to change)
@@ -140,7 +141,7 @@
         """return the filepath that will be used to cache concatenation of `paths`
         """
         _, ext = osp.splitext(paths[0])
-        fname = 'cache_concat_' + hashlib.md5(';'.join(paths)).hexdigest() + ext
+        fname = 'cache_concat_' + hashlib.md5((';'.join(paths)).encode('ascii')).hexdigest() + ext
         return osp.join(self.config.appdatahome, 'uicache', fname)
 
     def concat_cached_filepath(self, paths):
@@ -167,7 +168,7 @@
                             with open(osp.join(dirpath, rid), 'rb') as source:
                                 for line in source:
                                     f.write(line)
-                            f.write('\n')
+                            f.write(b'\n')
                     f.close()
                 except:
                     os.remove(tmpfile)
@@ -200,11 +201,13 @@
             paths = relpath[len(self.data_modconcat_basepath):].split(',')
             filepath = self.concat_files_registry.concat_cached_filepath(paths)
         else:
-            # skip leading '/data/' and url params
-            if relpath.startswith(self.base_datapath):
-                prefix = self.base_datapath
-            else:
+            if not relpath.startswith(self.base_datapath):
+                # /data/foo, redirect to /data/{hash}/foo
                 prefix = 'data/'
+                relpath = relpath[len(prefix):]
+                raise Redirect(self._cw.data_url(relpath), 302)
+            # skip leading '/data/{hash}/' and url params
+            prefix = self.base_datapath
             relpath = relpath[len(prefix):]
             relpath = relpath.split('?', 1)[0]
             dirpath, rid = config.locate_resource(relpath)
--- a/web/views/tableview.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/tableview.py	Thu Dec 10 12:34:15 2015 +0100
@@ -42,7 +42,7 @@
 .. autoclass:: cubicweb.web.views.tableview.TableLayout
    :members:
 
-There is by default only on table layout, using the 'table_layout' identifier,
+There is by default only one table layout, using the 'table_layout' identifier,
 that is referenced by table views
 :attr:`cubicweb.web.views.tableview.TableMixIn.layout_id`.  If you want to
 customize the look and feel of your table, you can either replace the default
@@ -52,21 +52,24 @@
 Notice you can gives options to the layout using a `layout_args` dictionary on
 your class.
 
-If you can still find a view that suit your needs, you should take a look at the
+If you still can't find a view that suit your needs, you should take a look at the
 class below that is the common abstract base class for the three views defined
-above and implements you own class.
+above and implement your own class.
 
 .. autoclass:: cubicweb.web.views.tableview.TableMixIn
    :members:
 """
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from warnings import warn
 from copy import copy
 from types import MethodType
 
+from six import string_types, add_metaclass, create_bound_method
+from six.moves import range
+
 from logilab.mtconverter import xml_escape
 from logilab.common.decorators import cachedproperty
 from logilab.common.deprecation import class_deprecated
@@ -162,7 +165,7 @@
 
     def __init__(self, req, view, **kwargs):
         super(TableLayout, self).__init__(req, **kwargs)
-        for key, val in self.cw_extra_kwargs.items():
+        for key, val in list(self.cw_extra_kwargs.items()):
             if hasattr(self.__class__, key) and not key[0] == '_':
                 setattr(self, key, val)
                 self.cw_extra_kwargs.pop(key)
@@ -225,7 +228,7 @@
 
     def render_table_body(self, w, colrenderers):
         w(u'<tbody>')
-        for rownum in xrange(self.view.table_size):
+        for rownum in range(self.view.table_size):
             self.render_row(w, rownum, colrenderers)
         w(u'</tbody>')
 
@@ -284,7 +287,7 @@
         attrs = renderer.attributes.copy()
         if renderer.sortable:
             sortvalue = renderer.sortvalue(rownum)
-            if isinstance(sortvalue, basestring):
+            if isinstance(sortvalue, string_types):
                 sortvalue = sortvalue[:self.sortvalue_limit]
             if sortvalue is not None:
                 attrs[u'cubicweb:sortvalue'] = js_dumps(sortvalue)
@@ -646,10 +649,10 @@
         # compute displayed columns
         if self.displaycols is None:
             if headers is not None:
-                displaycols = range(len(headers))
+                displaycols = list(range(len(headers)))
             else:
                 rqlst = self.cw_rset.syntax_tree()
-                displaycols = range(len(rqlst.children[0].selection))
+                displaycols = list(range(len(rqlst.children[0].selection)))
         else:
             displaycols = self.displaycols
         # compute table headers
@@ -723,7 +726,7 @@
             for aname, member in[('renderfunc', renderfunc),
                                  ('sortfunc', sortfunc)]:
                 if isinstance(member, MethodType):
-                    member = MethodType(member.im_func, acopy, acopy.__class__)
+                    member = create_bound_method(member.__func__, acopy)
                 setattr(acopy, aname, member)
             return acopy
         finally:
@@ -918,13 +921,13 @@
 ################################################################################
 
 
+@add_metaclass(class_deprecated)
 class TableView(AnyRsetView):
     """The table view accepts any non-empty rset. It uses introspection on the
     result set to compute column names and the proper way to display the cells.
 
     It is however highly configurable and accepts a wealth of options.
     """
-    __metaclass__ = class_deprecated
     __deprecation_warning__ = '[3.14] %(cls)s is deprecated'
     __regid__ = 'table'
     title = _('table')
@@ -977,9 +980,9 @@
             if 'displaycols' in self._cw.form:
                 displaycols = [int(idx) for idx in self._cw.form['displaycols']]
             elif headers is not None:
-                displaycols = range(len(headers))
+                displaycols = list(range(len(headers)))
             else:
-                displaycols = range(len(self.cw_rset.syntax_tree().children[0].selection))
+                displaycols = list(range(len(self.cw_rset.syntax_tree().children[0].selection)))
         return displaycols
 
     def _setup_tablesorter(self, divid):
@@ -1143,7 +1146,7 @@
             else:
                 column.append_renderer(subvid or 'incontext', colindex)
             if cellattrs and colindex in cellattrs:
-                for name, value in cellattrs[colindex].iteritems():
+                for name, value in cellattrs[colindex].items():
                     column.add_attr(name, value)
             # add column
             columns.append(column)
@@ -1184,8 +1187,8 @@
     title = _('editable-table')
 
 
+@add_metaclass(class_deprecated)
 class CellView(EntityView):
-    __metaclass__ = class_deprecated
     __deprecation_warning__ = '[3.14] %(cls)s is deprecated'
     __regid__ = 'cell'
     __select__ = nonempty_rset()
@@ -1271,6 +1274,7 @@
     finalview = 'editable-final'
 
 
+@add_metaclass(class_deprecated)
 class EntityAttributesTableView(EntityView):
     """This table displays entity attributes in a table and allow to set a
     specific method to help building cell content for each attribute as well as
@@ -1282,7 +1286,6 @@
     Table will render column header using the method header_for_COLNAME if
     defined otherwise COLNAME will be used.
     """
-    __metaclass__ = class_deprecated
     __deprecation_warning__ = '[3.14] %(cls)s is deprecated'
     __abstract__ = True
     columns = ()
@@ -1298,7 +1301,7 @@
         self.w(u'<table class="%s">' % self.table_css)
         self.table_header(sample)
         self.w(u'<tbody>')
-        for row in xrange(self.cw_rset.rowcount):
+        for row in range(self.cw_rset.rowcount):
             self.cell_call(row=row, col=0)
         self.w(u'</tbody>')
         self.w(u'</table>')
@@ -1333,4 +1336,3 @@
                 colname = self._cw._(column)
             self.w(u'<th>%s</th>' % xml_escape(colname))
         self.w(u'</tr></thead>\n')
-
--- a/web/views/tabs.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/tabs.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,7 +18,9 @@
 """base classes to handle tabbed views"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
+
+from six import string_types
 
 from logilab.common.deprecation import class_renamed
 from logilab.mtconverter import xml_escape
@@ -114,7 +116,7 @@
         active_tab = uilib.domid(default_tab)
         viewsvreg = self._cw.vreg['views']
         for tab in tabs:
-            if isinstance(tab, basestring):
+            if isinstance(tab, string_types):
                 tabid, tabkwargs = tab, {}
             else:
                 tabid, tabkwargs = tab
--- a/web/views/timetable.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/timetable.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,7 +18,9 @@
 """html timetable views"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
+
+from six.moves import range
 
 from logilab.mtconverter import xml_escape
 from logilab.common.date import ONEDAY, date_range, todatetime
@@ -51,7 +53,7 @@
         users = []
         users_max = {}
         # XXX: try refactoring with calendar.py:OneMonthCal
-        for row in xrange(self.cw_rset.rowcount):
+        for row in range(self.cw_rset.rowcount):
             task = self.cw_rset.get_entity(row, 0)
             icalendarable = task.cw_adapt_to('ICalendarable')
             if len(self.cw_rset[row]) > 1 and self.cw_rset.description[row][1] == 'CWUser':
@@ -88,7 +90,7 @@
 
         rows = []
         # colors here are class names defined in cubicweb.css
-        colors = ["col%x" % i for i in xrange(12)]
+        colors = ["col%x" % i for i in range(12)]
         next_color_index = 0
 
         visited_tasks = {} # holds a description of a task for a user
--- a/web/views/treeview.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/treeview.py	Thu Dec 10 12:34:15 2015 +0100
@@ -20,7 +20,7 @@
 """
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from warnings import warn
 
@@ -140,7 +140,7 @@
             ajaxargs = json.loads(form.pop('morekwargs'))
             # got unicode & python keywords must be strings
             morekwargs.update(dict((str(k), v)
-                                   for k, v in ajaxargs.iteritems()))
+                                   for k, v in ajaxargs.items()))
         toplevel_thru_ajax = form.pop('treeview_top', False) or initial_thru_ajax
         toplevel = toplevel_thru_ajax or (initial_load and not form.get('fname'))
         return subvid, treeid, toplevel_thru_ajax, toplevel
--- a/web/views/uicfg.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/uicfg.py	Thu Dec 10 12:34:15 2015 +0100
@@ -57,6 +57,8 @@
 
 from warnings import warn
 
+from six import string_types
+
 from cubicweb import neg_role
 from cubicweb.rtags import (RelationTags, RelationTagsBool, RelationTagsSet,
                             RelationTagsDict, NoTargetRelationTagsDict,
@@ -267,7 +269,7 @@
         if not 'inlined' in sectdict:
             sectdict['inlined'] = sectdict['main']
         # recompute formsections and set it to avoid recomputing
-        for formtype, section in sectdict.iteritems():
+        for formtype, section in sectdict.items():
             formsections.add('%s_%s' % (formtype, section))
 
     def tag_relation(self, key, formtype, section):
@@ -302,7 +304,7 @@
                 rtags[section] = value
         cls = self.tag_container_cls
         rtags = cls('_'.join([section,value])
-                    for section,value in rtags.iteritems())
+                    for section,value in rtags.items())
         return rtags
 
     def get(self, *key):
@@ -650,7 +652,7 @@
                 self.tag_relation((sschema, rschema, oschema, role), True)
 
     def _tag_etype_attr(self, etype, attr, desttype='*', *args, **kwargs):
-        if isinstance(attr, basestring):
+        if isinstance(attr, string_types):
             attr, role = attr, 'subject'
         else:
             attr, role = attr
@@ -687,5 +689,5 @@
 
 
 def registration_callback(vreg):
-    vreg.register_all(globals().itervalues(), __name__)
+    vreg.register_all(globals().values(), __name__)
     indexview_etype_section.init(vreg.schema)
--- a/web/views/undohistory.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/undohistory.py	Thu Dec 10 12:34:15 2015 +0100
@@ -17,7 +17,7 @@
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 
 from logilab.common.registry import Predicate
@@ -46,7 +46,7 @@
 
     def __str__(self):
         return '%s(%s)' % (self.__class__.__name__, ', '.join(
-            "%s=%v" % (str(k), str(v)) for k, v in kwargs.iteritems() ))
+            "%s=%v" % (str(k), str(v)) for k, v in kwargs.items() ))
 
     def __call__(self, cls, req, tx_action=None, **kwargs):
         # tx_action is expected to be a transaction.AbstractAction
--- a/web/views/urlpublishing.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/urlpublishing.py	Thu Dec 10 12:34:15 2015 +0100
@@ -60,7 +60,7 @@
 from rql import TypeResolverException
 
 from cubicweb import RegistryException
-from cubicweb.web import NotFound, Redirect, component
+from cubicweb.web import NotFound, Redirect, component, views
 
 
 class PathDontMatch(Exception):
@@ -201,18 +201,14 @@
             return self.handle_etype_attr(req, cls, attrname, value)
         return self.handle_etype(req, cls)
 
-    def set_vid_for_rset(self, req, cls, rset):# cls is there to ease overriding
+    def set_vid_for_rset(self, req, cls, rset):  # cls is there to ease overriding
         if rset.rowcount == 0:
             raise NotFound()
-        # we've to set a default vid here, since vid_from_rset may try to use a
-        # table view if fetch_rql include some non final relation
-        if rset.rowcount == 1:
-            req.form.setdefault('vid', 'primary')
-        else: # rset.rowcount >= 1
-            if len(rset.column_types(0)) > 1:
-                req.form.setdefault('vid', 'list')
-            else:
-                req.form.setdefault('vid', 'sameetypelist')
+        if 'vid' not in req.form:
+            # check_table=False tells vid_from_rset not to try to use a table view if fetch_rql
+            # include some non final relation
+            req.form['vid'] = views.vid_from_rset(req, rset, req.vreg.schema,
+                                                  check_table=False)
 
     def handle_etype(self, req, cls):
         rset = req.execute(cls.fetch_rql(req.user))
--- a/web/views/urlrewrite.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/urlrewrite.py	Thu Dec 10 12:34:15 2015 +0100
@@ -19,6 +19,8 @@
 
 import re
 
+from six import string_types, add_metaclass
+
 from cubicweb.uilib import domid
 from cubicweb.appobject import AppObject
 
@@ -51,6 +53,7 @@
         return super(metarewriter, mcs).__new__(mcs, name, bases, classdict)
 
 
+@add_metaclass(metarewriter)
 class URLRewriter(AppObject):
     """Base class for URL rewriters.
 
@@ -64,7 +67,6 @@
     should be tried first. The higher the priority is, the earlier the
     rewriter will be tried.
     """
-    __metaclass__ = metarewriter
     __registry__ = 'urlrewriting'
     __abstract__ = True
     priority = 1
@@ -122,14 +124,14 @@
                 required_groups = None
             if required_groups and not req.user.matching_groups(required_groups):
                 continue
-            if isinstance(inputurl, basestring):
+            if isinstance(inputurl, string_types):
                 if inputurl == uri:
                     req.form.update(infos)
                     break
             elif inputurl.match(uri): # it's a regexp
                 # XXX what about i18n? (vtitle for instance)
                 for param, value in infos.items():
-                    if isinstance(value, basestring):
+                    if isinstance(value, string_types):
                         req.form[param] = inputurl.sub(value, uri)
                     else:
                         req.form[param] = value
@@ -222,7 +224,7 @@
                 required_groups = None
             if required_groups and not req.user.matching_groups(required_groups):
                 continue
-            if isinstance(inputurl, basestring):
+            if isinstance(inputurl, string_types):
                 if inputurl == uri:
                     return callback(inputurl, uri, req, self._cw.vreg.schema)
             elif inputurl.match(uri): # it's a regexp
--- a/web/views/vcard.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/vcard.py	Thu Dec 10 12:34:15 2015 +0100
@@ -23,7 +23,7 @@
 from cubicweb.predicates import is_instance
 from cubicweb.view import EntityView
 
-_ = unicode
+from cubicweb import _
 
 VCARD_PHONE_TYPES = {'home': 'HOME', 'office': 'WORK', 'mobile': 'CELL', 'fax': 'FAX'}
 
--- a/web/views/wdoc.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/wdoc.py	Thu Dec 10 12:34:15 2015 +0100
@@ -35,7 +35,7 @@
 from cubicweb.view import StartupView
 from cubicweb.uilib import rest_publish
 from cubicweb.web import NotFound, action
-_ = unicode
+from cubicweb import _
 
 # table of content management #################################################
 
@@ -73,7 +73,7 @@
 
 def build_toc(config):
     alltocfiles = reversed(tuple(config.locate_all_files('toc.xml')))
-    maintoc = parse(alltocfiles.next()).getroot()
+    maintoc = parse(next(alltocfiles)).getroot()
     maintoc.parent = None
     index = {}
     build_toc_index(maintoc, index)
@@ -229,4 +229,3 @@
 
     def url(self):
         return self._cw.build_url('doc/about')
-
--- a/web/views/workflow.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/workflow.py	Thu Dec 10 12:34:15 2015 +0100
@@ -22,11 +22,13 @@
 """
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 import os
 from warnings import warn
 
+from six import add_metaclass
+
 from logilab.mtconverter import xml_escape
 from logilab.common.graph import escape
 from logilab.common.deprecation import class_deprecated
@@ -116,7 +118,7 @@
             'changestate', self._cw, entity=entity, transition=transition,
             redirect_path=self.redirectpath(entity), **kwargs)
         trinfo = self._cw.vreg['etypes'].etype_class('TrInfo')(self._cw)
-        trinfo.eid = self._cw.varmaker.next()
+        trinfo.eid = next(self._cw.varmaker)
         subform = self._cw.vreg['forms'].select('edition', self._cw, entity=trinfo,
                                                 mainform=False)
         subform.field_by_name('wf_info_for', 'subject').value = entity.eid
@@ -429,8 +431,8 @@
         return WorkflowDotPropsHandler(self._cw)
 
 
+@add_metaclass(class_deprecated)
 class TmpPngView(TmpFileViewMixin, EntityView):
-    __metaclass__ = class_deprecated
     __deprecation_warning__ = '[3.18] %(cls)s is deprecated'
     __regid__ = 'tmppng'
     __select__ = match_form_params('tmpfile')
--- a/web/views/xbel.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/xbel.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,7 +18,9 @@
 """xbel views"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
+
+from six.moves import range
 
 from logilab.mtconverter import xml_escape
 
@@ -42,7 +44,7 @@
         self.w(u'<!DOCTYPE xbel PUBLIC "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML" "http://www.python.org/topics/xml/dtds/xbel-1.0.dtd">')
         self.w(u'<xbel version="1.0">')
         self.w(u'<title>%s</title>' % self._cw._('bookmarks'))
-        for i in xrange(self.cw_rset.rowcount):
+        for i in range(self.cw_rset.rowcount):
             self.cell_call(i, 0)
         self.w(u"</xbel>")
 
@@ -65,4 +67,3 @@
 
     def url(self, entity):
         return entity.actual_url()
-
--- a/web/views/xmlrss.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/views/xmlrss.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,11 +18,13 @@
 """base xml and rss views"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 from base64 import b64encode
 from time import timezone
 
+from six.moves import range
+
 from logilab.mtconverter import xml_escape
 
 from cubicweb.predicates import (is_instance, non_final_entity, one_line_rset,
@@ -64,7 +66,7 @@
         """display a list of entities by calling their <item_vid> view"""
         self.w(u'<?xml version="1.0" encoding="%s"?>\n' % self._cw.encoding)
         self.w(u'<%s size="%s">\n' % (self.xml_root, len(self.cw_rset)))
-        for i in xrange(self.cw_rset.rowcount):
+        for i in range(self.cw_rset.rowcount):
             self.cell_call(i, 0)
         self.w(u'</%s>\n' % self.xml_root)
 
@@ -256,7 +258,7 @@
     def call(self):
         """display a list of entities by calling their <item_vid> view"""
         self._open()
-        for i in xrange(self.cw_rset.rowcount):
+        for i in range(self.cw_rset.rowcount):
             self.cell_call(i, 0)
         self._close()
 
--- a/web/webconfig.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/webconfig.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,7 +18,7 @@
 """web ui configuration for cubicweb instances"""
 
 __docformat__ = "restructuredtext en"
-_ = unicode
+from cubicweb import _
 
 import os
 import hmac
@@ -26,6 +26,8 @@
 from os.path import join, exists, split, isdir
 from warnings import warn
 
+from six import text_type
+
 from logilab.common.decorators import cached, cachedproperty
 from logilab.common.deprecation import deprecated
 from logilab.common.configuration import merge_options
@@ -280,18 +282,7 @@
                 continue
             yield key, pdef
 
-    # don't use @cached: we want to be able to disable it while this must still
-    # be cached
-    def repository(self, vreg=None):
-        """return the instance's repository object"""
-        try:
-            return self.__repo
-        except AttributeError:
-            from cubicweb.repoapi import get_repository
-            repo = get_repository(config=self, vreg=vreg)
-            self.__repo = repo
-            return repo
-
+    @deprecated('[3.22] call req.cnx.repo.get_versions() directly')
     def vc_config(self):
         return self.repository().get_versions()
 
@@ -305,7 +296,7 @@
             user   = self['anonymous-user'] or None
             passwd = self['anonymous-password']
             if user:
-                user = unicode(user)
+                user = text_type(user)
         except KeyError:
             user, passwd = None, None
         except UnicodeDecodeError:
@@ -317,17 +308,17 @@
         """This random key/salt is used to sign content to be sent back by
         browsers, eg. in the error report form.
         """
-        return str(uuid4())
+        return str(uuid4()).encode('ascii')
 
     def sign_text(self, text):
         """sign some text for later checking"""
         # hmac.new expect bytes
-        if isinstance(text, unicode):
+        if isinstance(text, text_type):
             text = text.encode('utf-8')
         # replace \r\n so we do not depend on whether a browser "reencode"
         # original message using \r\n or not
         return hmac.new(self._instance_salt,
-                        text.strip().replace('\r\n', '\n')).hexdigest()
+                        text.strip().replace(b'\r\n', b'\n')).hexdigest()
 
     def check_text_sign(self, text, signature):
         """check the text signature is equal to the given signature"""
@@ -472,7 +463,7 @@
             staticdir = join(staticdir, rdir)
             if not isdir(staticdir) and 'w' in mode:
                 os.makedirs(staticdir)
-        return file(join(staticdir, filename), mode)
+        return open(join(staticdir, filename), mode)
 
     def static_file_add(self, rpath, data):
         stream = self.static_file_open(rpath)
--- a/web/webctl.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/web/webctl.py	Thu Dec 10 12:34:15 2015 +0100
@@ -18,6 +18,7 @@
 """cubicweb-ctl commands and command handlers common to twisted/modpython
 web configuration
 """
+from __future__ import print_function
 
 __docformat__ = "restructuredtext en"
 
@@ -44,7 +45,7 @@
     def bootstrap(self, cubes, automatic=False, inputlevel=0):
         """bootstrap this configuration"""
         if not automatic:
-            print '\n' + underline_title('Generic web configuration')
+            print('\n' + underline_title('Generic web configuration'))
             config = self.config
             config.input_config('web', inputlevel)
             if ASK.confirm('Allow anonymous access ?', False):
@@ -87,8 +88,8 @@
             copy(osp.join(resource_dir, resource_path), dest_resource)
         # handle md5 version subdirectory
         linkdir(dest, osp.join(dest, config.instance_md5_version()))
-        print ('You can use apache rewrite rule below :\n'
-               'RewriteRule ^/data/(.*) %s/$1 [L]' % dest)
+        print('You can use apache rewrite rule below :\n'
+              'RewriteRule ^/data/(.*) %s/$1 [L]' % dest)
 
     def _datadirs(self, config, repo=None):
         if repo is None:
--- a/wsgi/__init__.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/wsgi/__init__.py	Thu Dec 10 12:34:15 2015 +0100
@@ -27,11 +27,9 @@
 __docformat__ = "restructuredtext en"
 
 from email import message, message_from_string
-from Cookie import SimpleCookie
-from StringIO import StringIO
-from cgi import parse_header
 from pprint import pformat as _pformat
 
+from six.moves.http_cookies import SimpleCookie
 
 def pformat(obj):
     """pretty prints `obj` if possible"""
--- a/wsgi/handler.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/wsgi/handler.py	Thu Dec 10 12:34:15 2015 +0100
@@ -19,7 +19,9 @@
 
 __docformat__ = "restructuredtext en"
 
-from itertools import chain, repeat, izip
+from itertools import chain, repeat
+
+from six.moves import zip
 
 from cubicweb import AuthenticationError
 from cubicweb.web import DirectResponse
@@ -78,7 +80,7 @@
     def __init__(self, code, req, body=None):
         text = STATUS_CODE_TEXT.get(code, 'UNKNOWN STATUS CODE')
         self.status =  '%s %s' % (code, text)
-        self.headers = list(chain(*[izip(repeat(k), v)
+        self.headers = list(chain(*[zip(repeat(k), v)
                                     for k, v in req.headers_out.getAllRawHeaders()]))
         self.headers = [(str(k), str(v)) for k, v in self.headers]
         if body:
--- a/wsgi/request.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/wsgi/request.py	Thu Dec 10 12:34:15 2015 +0100
@@ -27,13 +27,12 @@
 
 import tempfile
 
-from StringIO import StringIO
-from urllib import quote
-from urlparse import parse_qs
-from warnings import warn
+from io import BytesIO
+
+from six.moves.urllib.parse import parse_qs
 
 from cubicweb.multipart import (
-    copy_file, parse_form_data, MultipartError, parse_options_header)
+    copy_file, parse_form_data, parse_options_header)
 from cubicweb.web import RequestError
 from cubicweb.web.request import CubicWebRequestBase
 from cubicweb.wsgi import pformat, normalize_header
@@ -59,7 +58,7 @@
             length = 0
         # wsgi.input is not seekable, so copy the request contents to a temporary file
         if length < 100000:
-            self.content = StringIO()
+            self.content = BytesIO()
         else:
             self.content = tempfile.TemporaryFile()
         copy_file(environ['wsgi.input'], self.content, maxread=length)
@@ -82,7 +81,7 @@
                                                   headers= headers_in)
         self.content = environ['wsgi.input']
         if files is not None:
-            for key, part in files.iteritems():
+            for key, part in files.items():
                 self.form[key] = (part.filename, part.file)
 
     def __repr__(self):
@@ -149,15 +148,10 @@
         if params is None:
             return
         encoding = self.encoding
-        for param, val in params.iteritems():
+        for param, val in params.items():
             if isinstance(val, (tuple, list)):
-                val = [
-                    unicode(x, encoding) if isinstance(x, str) else x
-                    for x in val]
                 if len(val) == 1:
                     val = val[0]
-            elif isinstance(val, str):
-                val = unicode(val, encoding)
             if param in self.no_script_form_params and val:
                 val = self.no_script_form_param(param, val)
             if param == '_cwmsgid':
--- a/wsgi/test/unittest_wsgi.py	Wed Dec 09 18:42:13 2015 +0100
+++ b/wsgi/test/unittest_wsgi.py	Thu Dec 10 12:34:15 2015 +0100
@@ -1,7 +1,7 @@
 # encoding=utf-8
 
 import webtest.app
-from StringIO import StringIO
+from io import BytesIO
 
 from cubicweb.devtools.webtest import CubicWebTestTC
 
@@ -21,11 +21,11 @@
         r = webtest.app.TestRequest.blank('/', {
             'CONTENT_LENGTH': 12,
             'CONTENT_TYPE': 'text/plain',
-            'wsgi.input': StringIO('some content')})
+            'wsgi.input': BytesIO(b'some content')})
 
         req = CubicWebWsgiRequest(r.environ, self.vreg)
 
-        self.assertEqual('some content', req.content.read())
+        self.assertEqual(b'some content', req.content.read())
 
     def test_http_scheme(self):
         r = webtest.app.TestRequest.blank('/', {
@@ -52,11 +52,11 @@
         self.assertTrue(req.https)
 
     def test_big_content(self):
-        content = 'x'*100001
+        content = b'x'*100001
         r = webtest.app.TestRequest.blank('/', {
             'CONTENT_LENGTH': len(content),
             'CONTENT_TYPE': 'text/plain',
-            'wsgi.input': StringIO(content)})
+            'wsgi.input': BytesIO(content)})
 
         req = CubicWebWsgiRequest(r.environ, self.vreg)
 
@@ -94,14 +94,14 @@
 
     def test_post_files(self):
         content_type, params = self.webapp.encode_multipart(
-            (), (('filefield', 'aname', 'acontent'),))
+            (), (('filefield', 'aname', b'acontent'),))
         r = webtest.app.TestRequest.blank(
             '/', POST=params, content_type=content_type)
         req = CubicWebWsgiRequest(r.environ, self.vreg)
         self.assertIn('filefield', req.form)
         fieldvalue = req.form['filefield']
         self.assertEqual(u'aname', fieldvalue[0])
-        self.assertEqual('acontent', fieldvalue[1].read())
+        self.assertEqual(b'acontent', fieldvalue[1].read())
 
     def test_post_unicode_urlencoded(self):
         params = 'arg=%C3%A9'
@@ -115,3 +115,8 @@
         super(WSGIAppTC, cls).init_config(config)
         config.https_uiprops = None
         config.https_datadir_url = None
+
+
+if __name__ == '__main__':
+    import unittest
+    unittest.main()