[osm2pgrouting] 01/07: Imported Upstream version 2.2.0

Bas Couwenberg sebastic at debian.org
Sun Nov 13 00:13:25 UTC 2016


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

sebastic pushed a commit to branch master
in repository osm2pgrouting.

commit 6642762edd26d7a59a1d96d209f84d6583dd0f69
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Sun Nov 13 00:36:15 2016 +0100

    Imported Upstream version 2.2.0
---
 .travis.yml                         |  101 ++++
 AUTHORS.md                          |   18 +
 AUTHORS.txt                         |   10 -
 BOOST_LICENSE_1_0.txt               |   23 +
 CMakeLists.txt                      |   26 +-
 LICENSE.txt                         |  339 +++++++++++
 NEWS                                |   12 +-
 Readme.md                           |    8 +-
 ci/travis/install-postgres.sh       |   63 ++
 ci/travis/osm2pgrouting_build.sh    |   16 +
 ci/travis/pg_hba.conf               |   12 +
 mapconfig_for_bicycles.xml          |   60 ++
 mapconfig_for_cars.xml              |    2 -
 src/Class.cpp                       |   75 ++-
 src/Class.h                         |   71 +--
 src/Configuration.cpp               |   53 +-
 src/Configuration.h                 |   90 +--
 src/ConfigurationParserCallback.cpp |   71 +--
 src/ConfigurationParserCallback.h   |   67 ++-
 src/Export2DB.cpp                   | 1093 +++++++++++++++++++----------------
 src/Export2DB.h                     |  255 ++++----
 src/Node.cpp                        |   57 +-
 src/Node.h                          |   97 +++-
 src/OSMDocument.cpp                 |  190 +++---
 src/OSMDocument.h                   |   81 ++-
 src/OSMDocumentParserCallback.cpp   |  369 +++++-------
 src/OSMDocumentParserCallback.h     |   46 +-
 src/Relation.cpp                    |   52 +-
 src/Relation.h                      |   78 +--
 src/Type.cpp                        |   69 ++-
 src/Type.h                          |   82 +--
 src/Way.cpp                         |  338 ++++++++++-
 src/Way.h                           |  181 +++---
 src/XMLParser.cpp                   |   41 +-
 src/XMLParser.h                     |    7 +-
 src/math_functions.cpp              |   57 --
 src/math_functions.h                |   31 -
 src/osm2pgrouting.cpp               |  158 +++--
 src/osm_element.cpp                 |  105 ++++
 src/osm_element.h                   |   92 +++
 src/{Relation.cpp => osm_tag.cpp}   |   40 +-
 src/{Relation.h => osm_tag.h}       |   97 ++--
 src/{Way.cpp => print_progress.h}   |   72 +--
 src/prog_options.cpp                |   90 ++-
 src/prog_options.h                  |   35 +-
 src/utils.cpp                       |   31 -
 src/utils.h                         |    9 -
 tools/initial_commit.txt            |    1 +
 tools/spelling/fix_typos.sh         |   67 +++
 tools/spelling/typos_whitelist.txt  |   39 ++
 tools/vagrant/bootstrap.sh          |   22 -
 tools/vagrant/packaging.sh          |   15 -
 tools/vagrant/packaging.sh.sample   |   15 -
 53 files changed, 3198 insertions(+), 1931 deletions(-)

diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..a64d480
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,101 @@
+# ------------------------------------------------------------------------------
+# Travis CI scripts 
+# Copyright(c) pgRouting Contributors
+#
+# Main configuration
+# ------------------------------------------------------------------------------
+
+#choose precise or trusty
+
+#group: edge
+#dist: trusty    
+
+#dist: precise
+
+
+language: cpp
+
+compiler:
+    - gcc
+
+#notifications:
+#  email:
+#    on_failure: project at pgrouting.org
+
+env: POSTGRESQL_VERSION=9.6   PG_USER=postgres
+      
+matrix:
+  include:
+
+    - os: linux
+      sudo: required
+      dist: precise
+      env: POSTGRESQL_VERSION=9.5   PG_USER=postgres
+
+
+    - os: linux
+      sudo: required
+      dist: precise
+      env: POSTGRESQL_VERSION=9.4   PG_USER=postgres
+
+
+    - os: linux
+      sudo: required
+      dist: trusty
+      group: edge
+      env: POSTGRESQL_VERSION=9.6   PG_USER=postgres
+
+
+    - os: linux
+      sudo: required
+      dist: trusty
+      group: edge
+      env: POSTGRESQL_VERSION=9.5   PG_USER=postgres
+
+
+    - os: linux
+      sudo: required
+      dist: trusty
+      group: edge
+      env: POSTGRESQL_VERSION=9.4   PG_USER=postgres
+
+
+
+# executed. So things have to be tested oe by one.
+addons:
+  apt:
+    sources:
+      - - ubuntu-toolchain-r-test
+      # For cmake
+      - kubuntu-backports
+      - boost-latest
+    packages:
+      - cmake
+
+
+
+
+
+before_install:
+  - sudo sudo apt-get install -y libboost-program-options-dev
+
+install:
+  - sudo ./ci/travis/install-postgres.sh $POSTGRESQL_VERSION $PG_USER
+
+before_script:
+
+  # Add our chosen PG version to the path
+  - export PATH=/usr/lib/postgresql/$POSTGRESQL_VERSION/bin:$PATH
+
+  # initialize databases
+  #- createdb  -U $PG_USER ___pgr___test___
+
+
+script: 
+  - ./ci/travis/osm2pgrouting_build.sh
+
+#after_script: 
+  # blank
+
+#after_success:
+  # blank
diff --git a/AUTHORS.md b/AUTHORS.md
new file mode 100644
index 0000000..5edfb79
--- /dev/null
+++ b/AUTHORS.md
@@ -0,0 +1,18 @@
+# Project contributors:
+
+## pgROuting Team:
+
+* Daniel Kastl
+* Ko Nagase
+* Regina Obe
+* Virginia Vergara
+
+## Other contributors:
+
+* Adrien Pavie
+* Anton Patrushev
+* Daniel Wendt (Initial author) 
+* Jordan Anderson
+* J Kishore Kumar
+* Luís de Sousa
+* Sarthak Agarwal
diff --git a/AUTHORS.txt b/AUTHORS.txt
deleted file mode 100644
index d1d7bbc..0000000
--- a/AUTHORS.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-Project contributors:
-
-Daniel Wendt (primary author) 
-Anton Patrushev
-Daniel Kastl
-Jordan Anderson
-J Kishore Kumar
-Regina Obe
-Sarthak Agarwal
-Virginia Vergara
diff --git a/BOOST_LICENSE_1_0.txt b/BOOST_LICENSE_1_0.txt
new file mode 100644
index 0000000..36b7cd9
--- /dev/null
+++ b/BOOST_LICENSE_1_0.txt
@@ -0,0 +1,23 @@
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8c31186..0f5fcfd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,41 +6,45 @@ set (SHARE_DIR "/usr/share/osm2pgrouting")
 
 FIND_PACKAGE(PostgreSQL REQUIRED)
 FIND_PACKAGE(EXPAT REQUIRED)
-FIND_PACKAGE(Boost REQUIRED)
-FIND_PACKAGE(Boost 1.40 COMPONENTS program_options REQUIRED )
+
+FIND_PACKAGE(Boost)
+if(Boost_INCLUDE_DIRS)
+    message(STATUS "Boost headers were found here: ${Boost_INCLUDE_DIRS}")
+else(Boost_INCLUDE_DIRS)
+    message(FATAL_ERROR " Please check your Boost installation ") 
+endif(Boost_INCLUDE_DIRS)
+
+FIND_PACKAGE(Boost COMPONENTS program_options REQUIRED)
 
 FILE(GLOB SRC "${CMAKE_SOURCE_DIR}/src/*.cpp" "${CMAKE_SOURCE_DIR}/src/*.h")
 
-#set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FILE_OFFSET_BITS=64 -std=c++0x -fPIC -O2 -g -Wall -Wconversion -pedantic -fmax-errors=10 -Wextra  -frounding-math -Wno-deprecated")
-set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FILE_OFFSET_BITS=64 -std=c++0x -O2")
+set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FILE_OFFSET_BITS=64 -std=c++0x")
+set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Wconversion -pedantic -Wextra  -frounding-math -Wno-deprecated")
 
-#INCLUDE_DIRECTORIES(src ${POSTGRESQL_INCLUDE_DIR} ${EXPAT_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
 
-#ADD_EXECUTABLE(osm2pgrouting ${SRC})
-#TARGET_LINK_LIBRARIES(osm2pgrouting ${POSTGRESQL_LIBRARIES} ${EXPAT_LIBRARIES})
 
 message(STATUS "POSTGRESQL_INCLUDE_DIR: ${POSTGRESQL_INCLUDE_DIR}")
 message(STATUS "EXPAT_INCLUDE_DIRS: ${EXPAT_INCLUDE_DIRS}")
 message(STATUS "Boost_INCLUDE_DIRS: ${Boost_INCLUDE_DIRS}")
-message(STATUS "Boost_INCLUDE_DIR: ${Boost_INCLUDE_DIR}")
 message(STATUS "POSTGRESQL_LIBRARIES: ${POSTGRESQL_LIBRARIES}")
 message(STATUS "Boost_LIBRARIES: ${boost_LIBRARIES}")
 
-INCLUDE_DIRECTORIES(src ${POSTGRESQL_INCLUDE_DIR} ${EXPAT_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ${Boost_INCLUDE_DIR})
+INCLUDE_DIRECTORIES(src ${POSTGRESQL_INCLUDE_DIR} ${EXPAT_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
 
 ADD_EXECUTABLE(osm2pgrouting ${SRC})
 
 TARGET_LINK_LIBRARIES(osm2pgrouting ${POSTGRESQL_LIBRARIES} ${EXPAT_LIBRARIES} ${Boost_LIBRARIES} )
 
 INSTALL(TARGETS osm2pgrouting
-  RUNTIME DESTINATION "/usr/bin"
-)
+    RUNTIME DESTINATION "/usr/bin"
+    )
 
 INSTALL(FILES
     "${CMAKE_SOURCE_DIR}/COPYING"
     "${CMAKE_SOURCE_DIR}/Readme.md"
     "${CMAKE_SOURCE_DIR}/mapconfig.xml"
     "${CMAKE_SOURCE_DIR}/mapconfig_for_cars.xml"
+    "${CMAKE_SOURCE_DIR}/mapconfig_for_bicycles.xml"
     DESTINATION "${SHARE_DIR}")
 
 
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..d159169
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,339 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/NEWS b/NEWS
index febac42..56072f4 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,15 @@
+osm2pgRouting 2.2.0
 
-osm2pgRouting 2.1.0-alpha
+* Adding foreign keys to the tables.
+* Added a progress bar.
+* New mapconfig_for_bicycles.xml
+* Improved the C++ code.
+  * remove the use of pointers to avoid leaks.
+* Table `osm_ways_tags` because information is redundant.
+
+
+
+osm2pgRouting 2.1.0
 
    New "ways" table structure:
       Column       |           Type            |  Modifications
diff --git a/Readme.md b/Readme.md
index 5e5d1d2..5d7befd 100644
--- a/Readme.md
+++ b/Readme.md
@@ -1,5 +1,7 @@
 # osm2pgrouting
 
+[![Join the chat at https://gitter.im/pgRouting/osm2pgrouting](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/pgRouting/osm2pgrouting?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+
 ## Requirements
 
 Before you can use this tool for importing Openstreetmap data you need to install:
@@ -15,7 +17,7 @@ and to prepare a database.
 
 ## Documentation
 
-See in the documentation of the pgrouting website for more informations: http://pgrouting.org
+See in the documentation of the pgrouting website for more information: http://pgrouting.org
 
 ## Installation
 
@@ -60,8 +62,8 @@ Prepare the database:
 
 ```
 createdb routing
-psql -dbname routing -c 'CREATE EXTENSION postgis'
-psql -dbname routing -c 'CREATE EXTENSION pgRouting'
+psql --dbname routing -c 'CREATE EXTENSION postgis'
+psql --dbname routing -c 'CREATE EXTENSION pgRouting'
 ```
 
 Start the program like this:
diff --git a/ci/travis/install-postgres.sh b/ci/travis/install-postgres.sh
new file mode 100755
index 0000000..ecab98f
--- /dev/null
+++ b/ci/travis/install-postgres.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+# ------------------------------------------------------------------------------
+# Travis CI scripts 
+# Copyright(c) pgRouting Contributors
+#
+# Install pgRouting prerequesits
+# ------------------------------------------------------------------------------
+
+set -e
+
+POSTGRESQL_VERSION="$1"
+PGUSER="$2"
+
+if [[ -z "$POSTGRESQL_VERSION" ]] ; then
+    exit 1
+fi
+
+
+if [[ "$POSTGRESQL_VERSION" = "9.5" ||  "$POSTGRESQL_VERSION" = "9.6"  ]] ; then
+    POSTGIS_VERSION="2.3"
+fi
+
+echo "Postgres $POSTGRESQL_VERSION"
+echo "User $PGUSER"
+
+sudo /etc/init.d/postgresql stop
+sudo apt-get install -y \
+    postgresql-server-dev-$POSTGRESQL_VERSION
+
+if [[ "$POSTGRESQL_VERSION" = "9.5" ||  "$POSTGRESQL_VERSION" = "9.6"  ]] ; then
+
+    ## removing unused postgresql
+    #sudo apt-get -y remove --purge postgresql-9.1
+    #sudo apt-get -y remove --purge postgresql-9.2
+    #sudo apt-get -y remove --purge postgresql-9.3
+    #sudo apt-get -y remove --purge postgresql-9.4
+    #sudo apt-get -y remove --purge postgresql-9.5
+    #sudo apt-get -y remove --purge postgresql-9.6
+
+    echo "Installing postgresql $POSTGRESQL_VERSION  & postgis "
+
+    sudo apt-get install -y \
+        postgresql-$POSTGRESQL_VERSION \
+        postgresql-$POSTGRESQL_VERSION-postgis-$POSTGIS_VERSION
+
+    sudo cp /usr/lib/postgresql/$POSTGRESQL_VERSION/bin/pg_config /usr/bin/pg_config
+
+    sudo /etc/init.d/postgresql stop
+
+
+    sudo cat /etc/postgresql/$POSTGRESQL_VERSION/main/pg_hba.conf
+
+    sudo sed -i -e 's/port = 5433/port = 5432/g' /etc/postgresql/$POSTGRESQL_VERSION/main/postgresql.conf
+    sudo cp $TRAVIS_BUILD_DIR/ci/travis/pg_hba.conf /etc/postgresql/$POSTGRESQL_VERSION/main/pg_hba.conf
+
+    ps -fea | grep postgres
+fi
+
+sudo /etc/init.d/postgresql start $POSTGRESQL_VERSION
+
+# intall pgtap after postgres instance has started
+sudo apt-get install -y  postgresql-$POSTGRESQL_VERSION-pgtap
+sudo apt-get install -y libtap-parser-sourcehandler-pgtap-perl
diff --git a/ci/travis/osm2pgrouting_build.sh b/ci/travis/osm2pgrouting_build.sh
new file mode 100755
index 0000000..059181b
--- /dev/null
+++ b/ci/travis/osm2pgrouting_build.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# ------------------------------------------------------------------------------
+# Travis CI scripts 
+# Copyright(c) pgRouting Contributors
+#
+# Build pgRouting
+# ------------------------------------------------------------------------------
+
+# exit script on error
+set -e 
+
+# build pgRouting
+cmake  -DPOSTGRESQL_VERSION=$POSTGRESQL_VERSION
+make
+sudo make install
+
diff --git a/ci/travis/pg_hba.conf b/ci/travis/pg_hba.conf
new file mode 100755
index 0000000..8326a37
--- /dev/null
+++ b/ci/travis/pg_hba.conf
@@ -0,0 +1,12 @@
+# PostgreSQL Client Authentication Configuration File
+# ===================================================
+#
+# This file is configured to allow trusted authentication for Travis
+# automated installation and tests.
+#
+
+# Database administrative login by Unix domain socket
+local   all             postgres                                trust
+local   all             all                                     trust
+host    all             all             127.0.0.1/32            trust
+host    all             all             ::1/128                 trust
diff --git a/mapconfig_for_bicycles.xml b/mapconfig_for_bicycles.xml
new file mode 100644
index 0000000..4a7b7f5
--- /dev/null
+++ b/mapconfig_for_bicycles.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+  <type name="cycleway" id="1">
+    <class name="track" priority="1.0" id="101" />
+    <class name="lane" priority="1.5" id="102" />
+    <class name="opposite_lane" priority="1.5" id="103" />
+    <class name="opposite" priority="1.5" id="104" />
+    <class name="shared_lane" priority="1.6" id="105" />
+    <class name="shared" priority="1.6" id="106" />
+    <class name="share_busway" priority="1.6" id="107" />
+  </type>
+  <type name="cycleway:right" id="2">
+    <class name="track" priority="1.0" id="201" />
+    <class name="lane" priority="1.5" id="202" />
+    <class name="opposite_lane" priority="1.5" id="203" />
+    <class name="opposite" priority="1.5" id="204" />
+    <class name="shared_lane" priority="1.6" id="205" />
+    <class name="shared" priority="1.6" id="206" />
+    <class name="share_busway" priority="1.6" id="207" />
+  </type>
+  <type name="cycleway:left" id="3">
+    <class name="track" priority="1.0" id="301" />
+    <class name="lane" priority="1.5" id="302" />
+    <class name="opposite_lane" priority="1.5" id="303" />
+    <class name="opposite" priority="1.5" id="304" />
+    <class name="shared_lane" priority="1.6" id="305" />
+    <class name="shared" priority="1.6" id="306" />
+    <class name="share_busway" priority="1.6" id="307" />
+  </type>
+  <type name="tracktype" id="4">
+    <class name="grade1" priority="1.0" id="401" />
+    <class name="grade2" priority="1.1" id="402" />
+    <class name="grade3" priority="1.2" id="403" />
+    <class name="grade4" priority="1.3" id="404" />
+    <class name="grade5" priority="1.4" id="405" />
+  </type>
+  <type name="highway" id="5">
+    <class name="cycleway" priority="1.0" id="501" />
+    <class name="path" priority="1.1" id="502" />
+    <class name="pedestrian" priority="1.1" id="503" />
+    <class name="footway" priority="1.1" id="504" />
+    <class name="bridleway" priority="1.3" id="505" />
+    <class name="track" priority="1.0" id="506" />
+    <class name="living_street" priority="2.0" id="507" />
+    <class name="service" priority="2.0" id="508" />
+    <class name="residential" priority="2.2" id="509" />
+    <class name="unclassified" priority="2.3" id="510" />
+    <class name="tertiary_link" priority="2.5" id="511" />
+    <class name="tertiary" priority="2.5" id="512" />
+    <class name="services" priority="2.7" id="513" />
+    <class name="secondary_link" priority="3.0" id="514" />
+    <class name="secondary" priority="3.0" id="515" />
+    <class name="primary_link" priority="3.5" id="516" />
+    <class name="primary" priority="3.5" id="517" />
+    <class name="road" priority="4.0" id="500" />
+  </type>
+  <type name="junction" id="6">
+    <class name="roundabout" priority="2.5" id="601" />
+  </type>  
+</configuration>
\ No newline at end of file
diff --git a/mapconfig_for_cars.xml b/mapconfig_for_cars.xml
index 77f8454..d3084b0 100644
--- a/mapconfig_for_cars.xml
+++ b/mapconfig_for_cars.xml
@@ -1,5 +1,4 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<configuration>
   <type name="highway" id="1">
     <class name="motorway" id="101" priority="1.0" maxspeed="130" />
     <class name="motorway_link" id="102" priority="1.0" maxspeed="130" />
@@ -19,4 +18,3 @@
     <class name="unclassified" id="117" priority="3" maxspeed="90"/>
     <class name="road" id="100" priority="5" maxspeed="50" />
   </type> 
-</configuration>
diff --git a/src/Class.cpp b/src/Class.cpp
index 5784080..3e95f37 100644
--- a/src/Class.cpp
+++ b/src/Class.cpp
@@ -1,40 +1,57 @@
 /***************************************************************************
-*   Copyright (C) 2008 by Daniel Wendt                                    *
-*   gentoo.murray at gmail.com                                               *
-*                                                                         *
-*   This program is free software; you can redistribute it and/or modify  *
-*   it under the terms of the GNU General Public License as published by  *
-*   the Free Software Foundation; either version 2 of the License, or     *
-*   (at your option) any later version.                                   *
-*                                                                         *
-*   This program is distributed in the hope that it will be useful,       *
-*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
-*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
-*   GNU General Public License for more details.                          *
-*                                                                         *
-*   You should have received a copy of the GNU General Public License     *
-*   along with this program; if not, write to the                         *
-*   Free Software Foundation, Inc.,                                       *
-*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
-***************************************************************************/                  
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License t &or more details.                        *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#include <boost/lexical_cast.hpp>
 #include <string>
+
 #include "./Class.h"
 
 
 namespace osm2pgr {
 
-Class::Class(
-    int64_t id,
-    std::string name,
-    double priority,
-    int default_maxspeed
-    )
-:
-  id(id),
-  name(name),
-  priority(priority),
-  default_maxspeed(default_maxspeed) {
+
+Class::Class(const char **atts) :
+    m_priority(0),
+    m_default_maxspeed(50) {
+    auto **attribut = atts;
+    while (*attribut != NULL) {
+        std::string name = *attribut++;
+        std::string value = *attribut++;
+        if (name ==  "id") {
+            m_id = boost::lexical_cast<int64_t>(value);
+        } else if (name == "name") {
+            m_name = value;
+        } else if (name == "priority") {
+            m_priority = boost::lexical_cast<double>(value);
+        } else if (name == "maxspeed") {
+            m_default_maxspeed = boost::lexical_cast<int>(value);
+        } else {
+            auto tag_key = boost::lexical_cast<std::string>(name);
+            auto tag_value = boost::lexical_cast<std::string>(value);
+            m_tags[tag_key] = tag_value;
+        }
+    }
 }
 
 
+
+
+
 }  // end namespace osm2pgr
diff --git a/src/Class.h b/src/Class.h
index bb728b7..23e3c54 100644
--- a/src/Class.h
+++ b/src/Class.h
@@ -1,48 +1,51 @@
 /***************************************************************************
-*   Copyright (C) 2008 by Daniel Wendt                                    *
-*   gentoo.murray at gmail.com                                               *
-*                                                                         *
-*   This program is free software; you can redistribute it and/or modify  *
-*   it under the terms of the GNU General Public License as published by  *
-*   the Free Software Foundation; either version 2 of the License, or     *
-*   (at your option) any later version.                                   *
-*                                                                         *
-*   This program is distributed in the hope that it will be useful,       *
-*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
-*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
-*   GNU General Public License for more details.                          *
-*                                                                         *
-*   You should have received a copy of the GNU General Public License     *
-*   along with this program; if not, write to the                         *
-*   Free Software Foundation, Inc.,                                       *
-*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
-***************************************************************************/
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License t &or more details.                        *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
 #ifndef SRC_CLASS_H_
 #define SRC_CLASS_H_
 
+#include <map>
 #include <string>
 
 namespace osm2pgr {
 
 class Class {
  public:
-    int64_t id;
-    std::string name;
-    double priority;
-    int default_maxspeed;
- public:
-    /** 
-     *    Constructor
-     *    @param id ID of the class
-     *    @param name name of the class
-     */
-    Class(
-        int64_t id,
-        std::string name,
-        double priority,
-        int default_maxspeed);
+     Class() = default;
+     Class(const Class &) = default;
+     explicit Class(const char ** attributes);
+
+
+     inline int64_t id() const {return m_id;}
+     inline std::string name() const {return m_name;}
+     inline double priority() const {return m_priority;}
+     inline double default_maxspeed() const {return m_default_maxspeed;}
+
+ private:
+    int64_t m_id;
+    std::string m_name;
+    double m_priority;
+    double m_default_maxspeed;
+    std::map<std::string, std::string> m_tags;
 };
 
 
-}  // end namespace osm
+}  // end namespace osm2pgr
 #endif  // SRC_CLASS_H_
diff --git a/src/Configuration.cpp b/src/Configuration.cpp
index 6a69153..fd711bb 100644
--- a/src/Configuration.cpp
+++ b/src/Configuration.cpp
@@ -1,6 +1,6 @@
 /***************************************************************************
- *   Copyright (C) 2008 by Daniel Wendt   								   *
- *   gentoo.murray at gmail.com   											   *
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -10,7 +10,7 @@
  *   This program is distributed in the hope that it will be useful,       *
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
+ *   GNU General Public License t &or more details.                        *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
@@ -18,30 +18,41 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
-#include "Configuration.h"
-#include "Type.h"
-#include "Class.h"
+
+#include "./Configuration.h"
+#include <boost/lexical_cast.hpp>
+#include <iostream>
+#include <string>
+#include "./osm_tag.h"
+#include "./Type.h"
+#include "./Class.h"
 
 
 namespace osm2pgr {
 
-	Configuration::Configuration() {
-	}
 
-	Configuration::~Configuration() {
-		ez_mapdelete( m_Types );
-	}
+void Configuration::AddType(Type t) {
+    if (has_type(t.name())) {
+        std::cerr << "duplicate Type found in condfiguration file"
+            << t.name() << "\n";
+        return;
+    }
+    m_Types[t.name()] = t;
+}
 
-	void Configuration::AddType( Type* t ) {
-		m_Types[t->name] = t;
-	}
+Type& Configuration::FindType(std::string name) {
+    return m_Types.at(name);
+}
+Type Configuration::FindType(std::string name) const {
+    return m_Types.at(name);
+}
 
-	Type* Configuration::FindType( std::string name ) {
-		return m_Types[name];
-	}
+Class Configuration::FindClass(const Tag &tag) const {
+    return m_Types.at(tag.key()).classes()[tag.value()];
+}
 
-	Class* Configuration::FindClass( std::string typeName, std::string className ) {
-		return m_Types[typeName]->m_Classes[className];
-	}
+std::string Configuration::priority_str(const Tag &tag) const {
+    return  boost::lexical_cast<std::string>(FindClass(tag).priority());
+}
 
-} // end namespace osm
+}  // end namespace osm2pgr
diff --git a/src/Configuration.h b/src/Configuration.h
index 7d8b9bc..721c954 100644
--- a/src/Configuration.h
+++ b/src/Configuration.h
@@ -1,6 +1,6 @@
 /***************************************************************************
- *   Copyright (C) 2008 by Daniel Wendt                                    *
- *   gentoo.murray at gmail.com                                               *
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -10,61 +10,67 @@
  *   This program is distributed in the hope that it will be useful,       *
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
+ *   GNU General Public License t &or more details.                        *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
  *   Free Software Foundation, Inc.,                                       *
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
- 
-#ifndef CONFIGURATION_H
-#define CONFIGURATION_H
 
-#include "Type.h"
-#include "Class.h"
 
-namespace osm2pgr {
+#ifndef SRC_CONFIGURATION_H_
+#define SRC_CONFIGURATION_H_
 
-template< class Map >
-void ez_mapdelete( Map& c ) {
-	auto it(c.begin());
-	auto last(c.end());
-	while(it!=last) {
-		delete (*it++).second;
-	}
-}
+#include <string>
+#include <map>
+#include "Type.h"
+#include "./osm_tag.h"
+#include "./Class.h"
 
-template< class Vector >
-void ez_vectordelete( Vector& c ) {
-	auto it( c.begin() );
-	auto last( c.end() );
-	while( it!=last ) {
-		delete (*it++);
-	}
-}
-          
+namespace osm2pgr {
 
 /**
 A configuration document.
 */
-class Configuration
-{
-public:
-	//! Map, which saves the parsed types
-	std::map<std::string, Type*> m_Types;
-public:
+class Configuration {
+ public:
+     //! Constructor
+     Configuration() = default;
+
+     //! add node to the map
+     void AddType(Type t);
+     Type FindType(std::string typeName) const;
+     Type& FindType(std::string typeName);
+     Class FindClass(const Tag &tag) const;
+     std::string priority_str(const Tag &tag) const;
+
+
+     inline size_t has_class(const Tag &tag) const {
+         return has_type(tag.key())
+             && m_Types.at(tag.key()).has_class(tag.value());
+     }
+
+     double class_default_maxspeed(const Tag &tag) const {
+         return m_Types.at(
+                 tag.key()).classes().at(tag.value()).default_maxspeed();
+     }
+
+     double class_priority(const Tag &tag) const {
+         return m_Types.at(tag.key()).classes().at(tag.value()).priority();
+     }
+
+     const std::map<std::string, Type>& types() const {return m_Types;}
+
+     inline bool has_type(const std::string &type_name) const {
+         return m_Types.count(type_name) != 0;
+     }
 
-	//! Constructor
-	Configuration();
-	//! Destructor
-	virtual ~Configuration();
-	//! add node to the map
-	void AddType( Type* t );
-	Type* FindType( std::string typeName );
-	Class* FindClass( std::string typeName, std::string className );
+ private:
+     //! Map, which saves the parsed types
+     std::map<std::string, Type> m_Types;
 };
 
 
-} // end namespace osm2pgr
-#endif
+}  // end namespace osm2pgr
+#endif  // SRC_CONFIGURATION_H_
diff --git a/src/ConfigurationParserCallback.cpp b/src/ConfigurationParserCallback.cpp
index f373a54..18b47cd 100644
--- a/src/ConfigurationParserCallback.cpp
+++ b/src/ConfigurationParserCallback.cpp
@@ -1,6 +1,6 @@
 /***************************************************************************
- *   Copyright (C) 2008 by Daniel Wendt                                      *
- *   gentoo.murray at gmail.com                                                  *
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -10,16 +10,19 @@
  *   This program is distributed in the hope that it will be useful,       *
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
+ *   GNU General Public License t &or more details.                        *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
  *   Free Software Foundation, Inc.,                                       *
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
-#include <string>
-#include <boost/lexical_cast.hpp>
+
 #include "./ConfigurationParserCallback.h"
+
+#include <boost/lexical_cast.hpp>
+
+#include <string>
 #include "./OSMDocument.h"
 #include "./Configuration.h"
 #include "./Type.h"
@@ -27,58 +30,16 @@
 
 namespace osm2pgr {
 
-/**
+/*!
     Parser callback for configuration files
 */
 void ConfigurationParserCallback::StartElement(
-    const char *name,
-    const char** atts) {
-    // std::cout << "SE for <" << name << ">" << std::endl;
+        const char *name,
+        const char** atts) {
     if (strcmp(name, "class") == 0) {
-        if (atts != NULL) {
-            int64_t id = -1;
-            std::string name;
-            double priority  =  1;
-            int maxspeed = 50;
-            const char** attribut = (const char**)atts;
-            while (*attribut != NULL) {
-                const char* key = *attribut++;
-                const char* value = *attribut++;
-                if (strcmp(key, "id") == 0) {
-                    id = atoll(value);
-                    // std::cout << "class id = " << id << std::endl;
-                } else if (strcmp(key, "name") == 0) {
-                    name = value;
-                    // std::cout << "class name = " << name << std::endl;
-                } else if (strcmp(key, "priority") == 0) {
-                    priority = boost::lexical_cast<double>(value);
-                } else if (strcmp(key, "maxspeed") == 0) {
-                    maxspeed = boost::lexical_cast<int>(value);
-                }
-            }
-            if (id > 0 && !name.empty()) {
-                m_pActType->AddClass(new Class(id, name, priority, maxspeed));
-            }
-        }
+         m_current->add_class(atts);
     } else if (strcmp(name, "type") == 0) {
-        if (atts != NULL) {
-            int64_t id(0);
-            std::string name;
-            const char** attribut = (const char**)atts;
-            while (*attribut != NULL) {
-                const char* key = *attribut++;
-                const char* value = *attribut++;
-                if (strcmp(key, "id") == 0) {
-                    id = atoll(value);
-
-                } else if (strcmp(key, "name") == 0) {
-                    name = value;
-                }
-            }
-            if (!name.empty()) {
-                m_pActType = new Type(id, name);
-            }
-        }
+        m_current = new Type(atts);
     } else if (strcmp(name, "configuration") == 0) {
     }
 }
@@ -86,9 +47,9 @@ void ConfigurationParserCallback::StartElement(
 
 void ConfigurationParserCallback::EndElement(const char* name) {
     if (strcmp(name, "type") == 0) {
-        m_rDocument.AddType(m_pActType);
-        m_pActType = 0;
+        m_config.AddType(*m_current);
+        delete m_current;
     }
 }
 
-}  // end namespace osm2pgr
+}  // namespace osm2pgr
diff --git a/src/ConfigurationParserCallback.h b/src/ConfigurationParserCallback.h
index 3f1216a..224963b 100644
--- a/src/ConfigurationParserCallback.h
+++ b/src/ConfigurationParserCallback.h
@@ -1,6 +1,6 @@
 /***************************************************************************
- *   Copyright (C) 2008 by Daniel Wendt                                      *
- *   gentoo.murray at gmail.com                                                  *
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -10,7 +10,7 @@
  *   This program is distributed in the hope that it will be useful,       *
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
+ *   GNU General Public License t &or more details.                        *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
@@ -18,8 +18,16 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
+
 #ifndef SRC_CONFIGURATIONPARSERCALLBACK_H_
 #define SRC_CONFIGURATIONPARSERCALLBACK_H_
+#pragma once
+
+#if __GNUC__ > 4 || \
+                    (__GNUC__ == 4 && (__GNUC_MINOR__ >= 6))
+#else
+#define nullptr NULL
+#endif
 
 #include <string.h>
 #include "XMLParser.h"
@@ -27,42 +35,33 @@
 
 namespace osm2pgr {
 
-    class Configuration;
-    class Type;
+class Configuration;
+class Type;
 
+/**
+  Parser callback for configuration files
+  */
+class ConfigurationParserCallback : public xml::XMLParserCallback {
+ public:
     /**
-      Parser callback for configuration files
-      */
-    class ConfigurationParserCallback : public xml::XMLParserCallback{
-        //! reference to a Configuration object
-        Configuration& m_rDocument;
-
-        //! current type, which will be parsed
-        Type* m_pActType;
+     *    Constructor
+     */
+    explicit ConfigurationParserCallback(Configuration& doc) :
+        m_config(doc),
+        m_current(nullptr) {
+        }
+ private:
+    //! reference to a Configuration object
+    Configuration& m_config;
 
-        virtual void StartElement(const char *name, const char** atts);
+    //! current type, which will be parsed
+    Type *m_current;
 
-        virtual void EndElement(const char* name);
-
-#if 0
-        virtual void SetContent(const char* ch, int len)=0;
-
-        virtual void ProcessingInstruction(const char* target, const char* data)=0;
-
-        virtual void CDataBlockInternal(const char *value, int len)=0;
-#endif
+    virtual void StartElement(const char *name, const char** atts);
 
-        public:
-        /**
-         *    Constructor
-         */
-        ConfigurationParserCallback(Configuration& doc)
-            :
-                m_rDocument(doc),
-                m_pActType(0) {
-                }
-    };  // class
+    virtual void EndElement(const char* name);
+};
 
-}  // end namespace osm
+}  // namespace osm2pgr
 
 #endif  // SRC_CONFIGURATIONPARSERCALLBACK_H_
diff --git a/src/Export2DB.cpp b/src/Export2DB.cpp
index 95a2951..e2d6e99 100644
--- a/src/Export2DB.cpp
+++ b/src/Export2DB.cpp
@@ -1,8 +1,6 @@
 /***************************************************************************
- *   Copyright (C) 2008 by Daniel Wendt                                    *
- *   gentoo.murray at gmail.com                                               *
- *   Copyright (C) 2015 by Vicky Vergara                                   *
- *   vicky_vergara at hotmail.com                                             *
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -12,7 +10,7 @@
  *   This program is distributed in the hope that it will be useful,       *
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
+ *   GNU General Public License t &or more details.                        *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
@@ -20,147 +18,156 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
-#include "Export2DB.h"
-#include "boost/algorithm/string/replace.hpp"
-#include "prog_options.h"
+
+#include "./Export2DB.h"
+
 #include <unistd.h>
+
 #include <iostream>
+#include <map>
+#include <string>
+#include <vector>
 
-#define TO_STR(x)    boost::lexical_cast<std::string>(x)
+#include "./print_progress.h"
+#include "boost/algorithm/string/replace.hpp"
 
 
-Export2DB::Export2DB(const  po::variables_map &vm)
-:     mycon(0),
-      conninf ( "host=" + vm["host"].as<std::string>()
+#include "./prog_options.h"
+
+namespace osm2pgr {
+
+template <typename T>
+static
+std::string
+TO_STR(const T &x) {
+    return  boost::lexical_cast<std::string>(x);
+}
+
+
+Export2DB::Export2DB(const  po::variables_map &vm) :
+    mycon(0),
+    conninf("host=" + vm["host"].as<std::string>()
             + " user=" +  vm["username"].as<std::string>()
             + " dbname=" + vm["dbname"].as<std::string>()
-            + " port=" + vm["port"].as<std::string>() ),
-    tables_schema( vm["schema"].as<std::string>() ),
-    tables_prefix( vm["prefix"].as<std::string>() ),
-    tables_suffix( vm["suffix"].as<std::string>() ) {
-
-        if(!vm["password"].as<std::string>().empty())
+            + " port=" + vm["port"].as<std::string>()),
+    tables_schema(vm["schema"].as<std::string>()),
+    tables_prefix(vm["prefix"].as<std::string>()),
+    tables_suffix(vm["suffix"].as<std::string>()) {
+        if (!vm["password"].as<std::string>().empty())
             this->conninf+=" password=" + vm["password"].as<std::string>();
 
-    create_types = std::string(
-               " type_id integer PRIMARY KEY,"
-               " name text"
-    );
-
-    create_way_tag = std::string(
-           " class_id integer,"
-           " way_id bigint"
-    );
-
-    create_nodes =std::string(
-        " node_id bigserial PRIMARY KEY,"
-        " osm_id bigint,"
-        " lon decimal(11,8),"
-        " lat decimal(11,8),"
-        " numOfUse int"
-    );
-
-        create_vertices =std::string(
-        " id bigserial PRIMARY KEY,"
-        " osm_id bigint,"
-        " cnt integer,"
-        " chk integer,"
-        " ein integer,"
-        " eout integer,"
-        " lon decimal(11,8),"
-        " lat decimal(11,8),"
-        " CONSTRAINT vertex_id UNIQUE(osm_id)"
-    );
-        create_ways =std::string(
-
-            " gid bigserial PRIMARY KEY,"
-            " class_id integer not null,"
-            " length double precision,"
-            " length_m double precision,"
-            " name text,"
-            " source bigint,"
-            " target bigint,"
-            " x1 double precision,"
-            " y1 double precision,"
-            " x2 double precision,"
-            " y2 double precision,"
-            " cost double precision,"
-            " reverse_cost double precision,"
-            " cost_s double precision, "
-            " reverse_cost_s double precision,"
-            " rule text,"
-            " one_way int, "  // 0 unknown, 1 yes(normal direction), 2 (2 way),
-                              // -1 reversed (1 way but geometry is reversed)
-                              // 3 - reversible (one way street but direction chnges on time)
-            " maxspeed_forward integer,"
-            " maxspeed_backward integer,"
-            " osm_id bigint,"
-            " source_osm bigint,"
-            " target_osm bigint,"
-            " priority double precision DEFAULT 1"
-        );
-        create_relations =std::string(
-           "relation_id bigint,"
-           " type_id integer,"
-           " class_id integer,"
-           " name text"
-        );
-        create_relations_ways =std::string(
-
-           " relation_id bigint,"
-           " way_id bigint,"
-           " type character varying(200)"
-       ); 
-       create_classes = std::string(
-           " class_id integer PRIMARY KEY,"
-           " type_id integer,"
-           " name text,"
-           " priority double precision,"
-           " default_maxspeed integer"
-       ); 
-
-}  // constructor
+        create_types = std::string(
+                " type_id integer PRIMARY KEY,"
+                " name text");
+
+        create_way_tag = std::string(
+                " class_id integer PRIMARY KEY,"
+                " way_id bigint");
+
+        create_nodes = std::string(
+                " node_id bigserial PRIMARY KEY,"
+                " osm_id bigint,"
+                " lon decimal(11,8),"
+                " lat decimal(11,8),"
+                " numOfUse int");
+
+        create_vertices = std::string(
+                " id bigserial PRIMARY KEY,"
+                " osm_id bigint,"
+                " cnt integer,"
+                " chk integer,"
+                " ein integer,"
+                " eout integer,"
+                " lon decimal(11,8),"
+                " lat decimal(11,8),"
+                " CONSTRAINT vertex_id UNIQUE(osm_id)");
+
+        create_ways = std::string(
+                " gid bigserial PRIMARY KEY,"
+                " class_id integer not null,"
+                " length double precision,"
+                " length_m double precision,"
+                " name text,"
+                " source bigint,"
+                " target bigint,"
+                " x1 double precision,"
+                " y1 double precision,"
+                " x2 double precision,"
+                " y2 double precision,"
+                " cost double precision,"
+                " reverse_cost double precision,"
+                " cost_s double precision, "
+                " reverse_cost_s double precision,"
+                " rule text,"
+                " one_way int, "  //  0 unknown, 1 yes(normal direction), 2 (2 way),
+                //  -1 reversed (1 way but geometry is reversed)
+                //  3 - reversible (one way street but direction chnges on time)
+                " maxspeed_forward integer,"
+                    " maxspeed_backward integer,"
+                    " osm_id bigint,"
+                    " source_osm bigint,"
+                    " target_osm bigint,"
+                    " priority double precision DEFAULT 1");
+
+        create_relations = std::string(
+                "relation_id bigint PRIMARY KEY,"
+                " type_id integer,"
+                " class_id integer,"
+                " name text");
+
+        create_relations_ways = std::string(
+                " relation_id bigint,"
+                " way_id bigint,"
+                " type character varying(200)");
+
+        create_classes = std::string(
+                " class_id integer PRIMARY KEY,"
+                " type_id integer,"
+                " name text,"
+                " priority double precision,"
+                " default_maxspeed integer");
+    }  //  constructor
 
 Export2DB::~Export2DB() {
     PQfinish(mycon);
 }
 
 int Export2DB::connect() {
-
-    cout << conninf<< endl;
-    mycon =PQconnectdb(conninf.c_str());
-
-    ConnStatusType type =PQstatus(mycon);
-        if(type==CONNECTION_BAD) {
-            cout << "connection failed: "<< PQerrorMessage(mycon) << endl;
-            return 1;
-        } else {
-            cout << "connection success"<< endl;
-            return 0;
-        }
-/***
-      CONNECTION_STARTED: Waiting for connection to be made.
-      CONNECTION_MADE: Connection OK; waiting to send.
-      CONNECTION_AWAITING_RESPONSE: Waiting for a response from the postmaster.
-      CONNECTION_AUTH_OK: Received authentication; waiting for backend start-up.
-      CONNECTION_SETENV: Negotiating environment.
-***/
+    cout << conninf << endl;
+    mycon = PQconnectdb(conninf.c_str());
+
+    ConnStatusType type = PQstatus(mycon);
+    if (type == CONNECTION_BAD) {
+        cout << "connection failed: "<< PQerrorMessage(mycon) << endl;
+        return 1;
+    } else {
+        cout << "connection success"<< endl;
+        return 0;
+    }
+    /***
+CONNECTION_STARTED: Waiting for connection to be made.
+CONNECTION_MADE: Connection OK; waiting to send.
+CONNECTION_AWAITING_RESPONSE: Waiting for a response from the postmaster.
+CONNECTION_AUTH_OK: Received authentication; waiting for backend start-up.
+CONNECTION_SETENV: Negotiating environment.
+     ***/
 }
 
 
 /*!
 
- CREATE TEMP TABLE table (
-    table_description
- );
+  CREATE TEMP TABLE table (
+  table_description
+  );
 
 */
-bool Export2DB::createTempTable (const std::string &table_description,
-                            const std::string &table) const {
-    std::string sql = 
-	"CREATE TEMP TABLE " + table + "("    // + schema + "." + prefix etc
+bool Export2DB::createTempTable(const std::string &table_description,
+        const std::string &table) const {
+    std::string sql =
+        "CREATE TEMP TABLE " + table + "("    //  + schema + "." + prefix etc
         + table_description + ")";
 
+
     PGresult *result = PQexec(mycon, sql.c_str());
     bool created = (PQresultStatus(result) == PGRES_COMMAND_OK);
 
@@ -170,13 +177,13 @@ bool Export2DB::createTempTable (const std::string &table_description,
 
 /*!
 
- CREATE TABLE table (
-    table_description,
-    constraint
- );
+  CREATE TABLE table (
+  table_description,
+  constraint
+  );
 
 */
-bool Export2DB::has_postGIS() const{
+bool Export2DB::has_postGIS() const {
     std::string sql = "SELECT * FROM pg_extension WHERE extname = 'postgis'";
     PGresult *result = PQexec(mycon, sql.c_str());
     if (PQresultStatus(result) != PGRES_TUPLES_OK) {
@@ -187,16 +194,16 @@ bool Export2DB::has_postGIS() const{
 }
 
 bool Export2DB::createTable(const std::string &table_description,
-                             const std::string &table,
-                            const std::string &constraint) const {
-    std::string sql = 
-	"CREATE TABLE " + table + "("    
+        const std::string &table,
+        const std::string &constraint) const {
+    std::string sql =
+        "CREATE TABLE " + table + "("
         + table_description + constraint + ");";
 
     PGresult *result = PQexec(mycon, sql.c_str());
     bool created = (PQresultStatus(result) == PGRES_COMMAND_OK);
 
-    std::cout << (created? "Creating '" : " Exists: '") << table <<"': OK\n" ;
+    std::cout << (created? "Creating '" : " Exists: '") << table <<"': OK\n";
 
     PQclear(result);
     return created;
@@ -208,32 +215,34 @@ void Export2DB::addGeometry(
         const std::string &geometry_type) const {
     std::cout << "   Adding Geometry: ";
     /** PostGIS requires the schema to be specified as separate arg if not default user's schema **/
-    std::string sql = 
-               + " SELECT AddGeometryColumn(" + ( schema == "" ? "" : "'" + schema + "' ," ) + " '" 
-               + table + "'," 
-               + "'the_geom', 4326, '" + geometry_type + "',2 );";
+    std::string sql =
+        + " SELECT AddGeometryColumn(" + (schema == "" ? "" : "'" + schema + "' ,") + " '"
+        + table + "',"
+        + "'the_geom', 4326, '" + geometry_type + "',2);";
+
 
     PGresult *result = PQexec(mycon, sql.c_str());
 
     if (PQresultStatus(result) != PGRES_TUPLES_OK) {
         std::cout << PQresultErrorMessage(result) << "<-------\n";
-        throw std::string(PQresultErrorMessage(result)) ;
+        throw std::string(PQresultErrorMessage(result));
     }
     PQclear(result);
 }
 
 void Export2DB::addTempGeometry(
-             const std::string &table,
-             const std::string &geometry_type) const {
-    std::string sql = 
-         " SELECT AddGeometryColumn('" 
-            + table + "'," 
-            + "'the_geom', 4326, '" + geometry_type + "',2 );";
+        const std::string &table,
+        const std::string &geometry_type) const {
+    std::string sql =
+        " SELECT AddGeometryColumn('"
+        + table + "',"
+        + "'the_geom', 4326, '" + geometry_type + "',2);";
+
 
     PGresult *result = PQexec(mycon, sql.c_str());
     if (PQresultStatus(result) != PGRES_TUPLES_OK) {
         std::cout << PQresultErrorMessage(result);
-        throw std::string(PQresultErrorMessage(result)) ;
+        throw std::string(PQresultErrorMessage(result));
     }
     PQclear(result);
 }
@@ -241,154 +250,181 @@ void Export2DB::addTempGeometry(
 
 void Export2DB::create_gindex(const std::string &index, const std::string &table) const {
     std::string sql = (
-         " CREATE INDEX " 
-             + index + "_gdx ON " 
-             + table + " using gist(the_geom);" );
+            " CREATE INDEX "
+            + index + "_gdx ON "
+            + table + " using gist(the_geom);");
     PGresult *result = PQexec(mycon, sql.c_str());
 
     if (PQresultStatus(result) != PGRES_COMMAND_OK) {
         std::cout << PQresultErrorMessage(result);
-        throw std::string(PQresultErrorMessage(result)) ;
+        throw std::string(PQresultErrorMessage(result));
     }
     PQclear(result);
 }
 
 void Export2DB::create_idindex(const std::string &colname, const std::string &table) const {
     std::string sql = (
-         " CREATE INDEX " 
-         "     ON " + table + 
-         "     USING btree ( " + colname + " );" );
+            " CREATE INDEX "
+            "     ON " + table +
+            "     USING btree (" + colname + ");");
     PGresult *result = PQexec(mycon, sql.c_str());
-    //TODO check missing
+    // TODO(who) check missing
     PQclear(result);
 }
 
-///////////////////////
-void Export2DB::createTables() const{
-    // the following are particular of the file tables
-    if (createTable( create_vertices, addSchema( full_table_name( "ways_vertices_pgr" ) )  )) {
-        addGeometry(default_tables_schema(), full_table_name( "ways_vertices_pgr" ), "POINT" );
-        create_gindex( full_table_name("ways_vertices_pgr"), addSchema( full_table_name("ways_vertices_pgr") ));
-        create_idindex( "osm_id", addSchema( full_table_name("ways_vertices_pgr") ));
+// /////////////////////
+void Export2DB::createTables() const {
+    auto ways_name = full_table_name("ways");
+    auto vertices_name = ways_name + "_vertices_pgr";
+
+    //  the following are particular of the file tables
+    if (createTable(create_vertices, addSchema(vertices_name))) {
+        addGeometry(default_tables_schema(), vertices_name, "POINT");
+        create_gindex(vertices_name, addSchema(vertices_name));
+        create_idindex("osm_id", addSchema(vertices_name));
     }
 
-    if (createTable( create_ways, addSchema( full_table_name("ways") ) )) {
-        addGeometry( default_tables_schema(), full_table_name("ways"), "LINESTRING" );
-        create_gindex( full_table_name("ways"), addSchema( full_table_name("ways") ));
-        create_idindex(  "source_osm", addSchema( full_table_name("ways") ));
-        create_idindex(  "target_osm", addSchema( full_table_name("ways") ));
-        create_idindex(  "source", addSchema( full_table_name("ways") ));
-        create_idindex(  "target", addSchema( full_table_name("ways") ));
+    if (createTable(create_ways, addSchema(ways_name))) {
+        addGeometry(default_tables_schema(), ways_name, "LINESTRING");
+        create_gindex(ways_name, addSchema(ways_name));
+        create_idindex("source_osm", addSchema(ways_name));
+        create_idindex("target_osm", addSchema(ways_name));
+        create_idindex("source", addSchema(ways_name));
+        create_idindex("target", addSchema(ways_name));
     }
 
-    createTable( create_relations_ways, addSchema( full_table_name("relations_ways") ) );
-
-    // the following are general tables
-    if ( createTable( create_nodes,
-                     addSchema( "osm_nodes"),
-                     ", CONSTRAINT node_id UNIQUE(osm_id)") )
-        addGeometry(default_tables_schema(), "osm_nodes", "POINT" );
-    createTable( create_relations,  addSchema( "osm_relations") );
-    createTable( create_way_tag, addSchema(  "osm_way_tags" ) );
-    createTable( create_types, addSchema(  "osm_way_types" ) );
-    createTable( create_classes, addSchema( "osm_way_classes" ) );
+    createTable(create_relations_ways, addSchema(full_table_name("relations_ways")));
+
+    //  the following are general tables
+    if (createTable(create_nodes,
+                addSchema("osm_nodes"),
+                ", CONSTRAINT node_id UNIQUE(osm_id)"))
+        addGeometry(default_tables_schema(), "osm_nodes", "POINT");
+    createTable(create_relations,  addSchema("osm_relations"));
+#if 0
+    createTable(create_way_tag, addSchema("osm_way_tags"));
+#endif
+    createTable(create_types, addSchema("osm_way_types"));
+    createTable(create_classes, addSchema("osm_way_classes"));
 }
 
 
 
 void Export2DB::dropTable(const std::string &table) const {
-    std::string drop_tables( "DROP TABLE IF EXISTS " +  table);
+    std::string drop_tables("DROP TABLE IF EXISTS " +  table);
     PGresult *result = PQexec(mycon, drop_tables.c_str());
     PQclear(result);
-}   
+}
 
 
 
 void Export2DB::dropTables() const {
-    dropTable( addSchema( full_table_name("ways") ) );
-    dropTable( addSchema( full_table_name("ways_vertices_pgr") ) );
-    dropTable( addSchema( full_table_name("relations_ways") ) );
+    auto ways_name = full_table_name("ways");
+    auto vertices_name = ways_name + "_vertices_pgr";
+
+    dropTable(addSchema(ways_name));
+    dropTable(addSchema(vertices_name));
 
-    // we are not deleting general tables osm_
+    dropTable(addSchema(full_table_name("relations_ways")));
+
+    //  we are not deleting general tables osm_
 }
 
 /*!
 
-Inserts the data into a temporary table
-Inserts the data to the final table only if
-**osm_id**
-doesnt exist already
+  Inserts the data into a temporary table
+  Inserts the data to the final table only if
+ **osm_id**
+ doesn't exist already
 
 */
-void Export2DB::exportNodes(const std::map<long long, Node*> &nodes) const {
-    std::cout << "    Processing " <<  nodes.size() <<  " nodes"  << ": ";
-
-    if (createTempTable( create_nodes, "__nodes_temp" ))
-       addTempGeometry( "__nodes_temp", "POINT" );
+void  Export2DB::prepareExportNodes(const std::string nodes_columns) const {
+    if (createTempTable(create_nodes, "__nodes_temp"))
+        addTempGeometry("__nodes_temp", "POINT");
 
-    std::string nodes_columns(" osm_id, lon, lat, numofuse, the_geom " );   
-    std::string copy_nodes( "COPY __nodes_temp (" + nodes_columns + ") FROM STDIN");
+    std::string copy_nodes("COPY __nodes_temp (" + nodes_columns + ") FROM STDIN");
     PGresult* q_result = PQexec(mycon, copy_nodes.c_str());
+    PQclear(q_result);
+}
 
-    if ( PQresultStatus(q_result) == PGRES_COPY_IN) {
-        for (const auto &n : nodes)
-        {
-            Node* node = n.second;
-            std::string row_data = TO_STR(node->id);
-            row_data += "\t";
-            row_data += TO_STR(node->lon);
-            row_data += "\t";
-            row_data += TO_STR(node->lat);
-            row_data += "\t";
-            row_data += TO_STR(node->numsOfUse);
-            row_data += "\t";
-            row_data += "srid=4326; POINT(" + TO_STR(node->lon) + " " + TO_STR(node->lat) + ")";
-            row_data += "\n";
-            PQputline(mycon, row_data.c_str());
+
+
+void Export2DB::exportNodes(const std::map<int64_t, Node> &nodes) const {
+    std::cout << "    Processing " <<  nodes.size() <<  " nodes"  << ":\n";
+    std::string nodes_columns(" osm_id, lon, lat, numofuse, the_geom ");
+
+    prepareExportNodes(nodes_columns);
+    uint32_t chunck_size = 20000;
+
+
+    int64_t count = 0;
+    for (auto it = nodes.begin(); it != nodes.end(); ++it) {
+        auto n = *it;
+
+        if ((count % (chunck_size / 100)) == 0) {
+            print_progress(nodes.size(), count);
+            std::cout << " Total Processed: " << count;
         }
-        PQputline(mycon, "\\.\n");
-        PQendcopy(mycon);
+
+        if ((++count % chunck_size) == 0) {
+            PQputline(mycon, "\\.\n");
+            PQendcopy(mycon);
+            processSectionExportNodes(nodes_columns);
+            prepareExportNodes(nodes_columns);
+        }
+
+        auto node = n.second;
+        std::string row_data = TO_STR(node.osm_id());
+        row_data += "\t";
+        row_data += node.geom_str("\t");
+        row_data += "\t";
+        row_data += TO_STR(node.numsOfUse());
+        row_data += "\t";
+        row_data += node.point_geometry();
+        row_data += "\n";
+        PQputline(mycon, row_data.c_str());
     }
-    PQclear(q_result);
 
+    print_progress(nodes.size(), count);
+    PQputline(mycon, "\\.\n");
+    PQendcopy(mycon);
+    processSectionExportNodes(nodes_columns);
+    std::cout << "\n";
+}
+
+
+void  Export2DB::processSectionExportNodes(const std::string nodes_columns) const {
     std::string insert_into_nodes(
-         " WITH data AS ( "
-         " SELECT a.* "
-         " FROM  __nodes_temp a LEFT JOIN  " + addSchema( "osm_nodes" ) + " b USING (osm_id) WHERE (b.osm_id IS NULL))"
-
-         " INSERT INTO "  + addSchema("osm_nodes") +  
-          "( " + nodes_columns + " ) "
-         " (SELECT " + nodes_columns + " FROM data); ");
-    q_result = PQexec(mycon, insert_into_nodes.c_str());
+            " WITH data AS ("
+            " SELECT a.* "
+            " FROM  __nodes_temp a LEFT JOIN  " + addSchema("osm_nodes") + " b USING (osm_id) WHERE (b.osm_id IS NULL))"
+
+            " INSERT INTO "  + addSchema("osm_nodes") +
+            "(" + nodes_columns + ") "
+            " (SELECT " + nodes_columns + " FROM data); ");
+    PGresult* q_result = PQexec(mycon, insert_into_nodes.c_str());
     PQclear(q_result);
-    std::cout << " Inserted: " << PQcmdTuples(q_result) << "\n";
-
     dropTable("__nodes_temp");
 }
 
+
 /*!
 
 */
 void Export2DB::fill_vertices_table(const std::string &table, const std::string &vertices_tab) const {
-    //std::cout << "Filling '" << vertices_tab << "' based on '" << table <<"'\n";
+    // std::cout << "Filling '" << vertices_tab << "' based on '" << table <<"'\n";
     std::string sql(
-        "WITH osm_vertex AS ( "
-             "(select source_osm as osm_id, x1 as lon, y1 as lat FROM " + table + " where source is NULL)"
-             " union "
-             "(select target_osm as osm_id, x2 as lon, y2 as lat FROM " + table + " where target is NULL)"
-          ") , "
-	  " data1 AS (SELECT osm_id, lon, lat FROM (SELECT DISTINCT * from osm_vertex) a "
-          ") "
-          " INSERT INTO " + vertices_tab + " (osm_id, lon, lat, the_geom) (SELECT data1.*, ST_SetSRID(ST_Point(lon, lat), 4326) FROM data1)");
+            "WITH osm_vertex AS ("
+            "(select source_osm as osm_id, x1 as lon, y1 as lat FROM " + table + " where source is NULL)"
+            " union "
+            "(select target_osm as osm_id, x2 as lon, y2 as lat FROM " + table + " where target is NULL)"
+            ") , "
+            " data1 AS (SELECT osm_id, lon, lat FROM (SELECT DISTINCT * from osm_vertex) a "
+            ") "
+            " INSERT INTO " + vertices_tab + " (osm_id, lon, lat, the_geom) (SELECT data1.*, ST_SetSRID(ST_Point(lon, lat), 4326) FROM data1)");
 
     PGresult* q_result = PQexec(mycon, sql.c_str());
     std::cout << "Vertices inserted " << PQcmdTuples(q_result);
-#if 0
-    if (PQresultStatus(q_result) == PGRES_COMMAND_OK) 
-         std::cout << " OK " << PQcmdStatus(q_result) << std::endl;
-    else
-         std::cout  << "   " << PQresultErrorMessage( q_result )  << std::endl;
-#endif
     PQclear(q_result);
 }
 
@@ -397,113 +433,116 @@ void Export2DB::fill_vertices_table(const std::string &table, const std::string
 
 
 void Export2DB::fill_source_target(const std::string &table, const std::string &vertices_tab) const {
-//    std::cout << "    Filling 'source' column of '" << table << "': ";
+    // std::cout << "    Filling 'source' column of '" << table << "': ";
     std::string sql1(
-        " UPDATE " + table + " AS w"
-        " SET source = v.id "
-        " FROM " + vertices_tab + " AS v"
-        " WHERE w.source is NULL and w.source_osm = v.osm_id;");
+            " UPDATE " + table + " AS w"
+            " SET source = v.id "
+            " FROM " + vertices_tab + " AS v"
+            " WHERE w.source is NULL and w.source_osm = v.osm_id;");
     PGresult* q_result = PQexec(mycon, sql1.c_str());
-//    std::cout << " Updated: " << PQcmdTuples(q_result) << " rows\n";
+    //     std::cout << " Updated: " << PQcmdTuples(q_result) << " rows\n";
     PQclear(q_result);
 
-//    std::cout << "    Filling 'target' column of '" << table << "': ";
+    //     std::cout << "    Filling 'target' column of '" << table << "': ";
     std::string sql2(
-        " UPDATE " + table + " AS w"
-        " SET target = v.id "
-        " FROM " + vertices_tab + " AS v"
-        " WHERE w.target is NULL and w.target_osm = v.osm_id;");
+            " UPDATE " + table + " AS w"
+            " SET target = v.id "
+            " FROM " + vertices_tab + " AS v"
+            " WHERE w.target is NULL and w.target_osm = v.osm_id;");
     q_result = PQexec(mycon, sql2.c_str());
-//    std::cout << " Updated: " << PQcmdTuples(q_result) << " rows\n";
+    //     std::cout << " Updated: " << PQcmdTuples(q_result) << " rows\n";
     PQclear(q_result);
 
-//    std::cout << "    Filling other columns of '" << table << "': ";
+    //     std::cout << "    Filling other columns of '" << table << "': ";
     std::string sql3(
-        " UPDATE " + table + 
-        " SET  length_m = st_length(geography(ST_Transform(the_geom, 4326))),"
-        "      cost_s = CASE "
-        "           WHEN one_way = -1 THEN -st_length(geography(ST_Transform(the_geom, 4326))) / (maxspeed_forward * 5 / 18)"
-        "           ELSE st_length(geography(ST_Transform(the_geom, 4326))) / (maxspeed_backward * 5 / 18)"
-        "             END, "
-        "      reverse_cost_s = CASE "
-        "           WHEN one_way = 1 THEN -st_length(geography(ST_Transform(the_geom, 4326))) / (maxspeed_backward * 5 / 18)"
-        "           ELSE st_length(geography(ST_Transform(the_geom, 4326))) / (maxspeed_backward * 5 / 18)"
-        "             END "
-	" WHERE length_m IS NULL;");
+            " UPDATE " + table +
+            " SET  length_m = st_length(geography(ST_Transform(the_geom, 4326))),"
+            "      cost_s = CASE "
+            "           WHEN one_way = -1 THEN -st_length(geography(ST_Transform(the_geom, 4326))) / (maxspeed_forward::float * 5.0 / 18.0)"
+            "           ELSE st_length(geography(ST_Transform(the_geom, 4326))) / (maxspeed_backward::float * 5.0 / 18.0)"
+            "             END, "
+            "      reverse_cost_s = CASE "
+            "           WHEN one_way = 1 THEN -st_length(geography(ST_Transform(the_geom, 4326))) / (maxspeed_backward::float * 5.0 / 18.0)"
+            "           ELSE st_length(geography(ST_Transform(the_geom, 4326))) / (maxspeed_backward::float * 5.0 / 18.0)"
+            "             END "
+            " WHERE length_m IS NULL;");
     q_result = PQexec(mycon, sql3.c_str());
-//    std::cout << " Updated: " << PQcmdTuples(q_result) << " rows\n";
+    // std::cout << " Updated: " << PQcmdTuples(q_result) << " rows\n";
     PQclear(q_result);
-
 }
 
 
-void Export2DB::exportRelations(const std::vector<Relation*> &relations, Configuration *config) const
-{
-    std::cout << "    Processing " << relations.size() << " relations\n";
-    createTempTable( create_relations, "__relations_temp" );
-    
-    std::string relations_columns("relation_id, type_id, class_id, name " );   
-    std::string copy_relations( "COPY __relations_temp (" + relations_columns + ") FROM STDIN");
+void Export2DB::exportRelations(
+        const std::vector<Relation> &relations,
+        const Configuration &config) const {
+    std::cout << "    Processing " << relations.size() << " relations:";
+    createTempTable(create_relations, "__relations_temp");
+
+    std::string relations_columns("relation_id, type_id, class_id, name ");
+    std::string copy_relations("COPY __relations_temp (" + relations_columns + ") FROM STDIN");
+
 
-    
     PGresult* q_result = PQexec(mycon, copy_relations.c_str());
-    for (const auto &relation : relations)
-    {
-std::cout << relation->m_Tags.size();
-        for (const auto &tag : relation->m_Tags)
-        {
-            // std::pair<std::string, std::string> pair = *it_tag++;
-            std::string row_data = TO_STR(relation->id);
-            row_data += "\t";
-            row_data += TO_STR(config->FindType(tag.first)->id);
-            row_data += "\t";
-            row_data += TO_STR(config->FindClass(tag.first, tag.second)->id);
-            row_data += "\t";
-            if(!relation->name.empty()) {
-                std::string escaped_name = relation->name;
-                boost::replace_all(escaped_name, "\t", "\\\t");
-                row_data += escaped_name;
-            }
-            row_data += "\n";
-std::cout << row_data << "\n";
-            PQputline(mycon, row_data.c_str());
-        }
+    for (auto it = relations.begin(); it != relations.end(); ++it) {
+        auto relation = *it;
+
+        std::string row_data = TO_STR(relation.osm_id());
+        row_data += "\t";
+        row_data += TO_STR(config.FindType(relation.tag_config().key()).id());
+        row_data += "\t";
+        row_data += TO_STR(config.FindClass(relation.tag_config()).id());
+        row_data += "\t";
+        row_data = row_data + relation.tag_config().key() + "=" + relation.tag_config().value();
+        row_data += "\n";
+        PQputline(mycon, row_data.c_str());
     }
     PQputline(mycon, "\\.\n");
     PQendcopy(mycon);
     PQclear(q_result);
     std::string insert_into_relations(
-         " WITH data AS ( "
-         " SELECT a.* "
-         " FROM  __relations_temp a LEFT JOIN " +  addSchema( "osm_relations" ) + " b USING (relation_id, type_id)"
-         "     WHERE (b.relation_id IS NULL OR b.type_id IS NULL)"
-
-         " INSERT INTO " + addSchema( "osm_relations" )  + " "
-          "( " + relations_columns + " ) "
-         " (SELECT " + relations_columns + " FROM data); ");
+            " WITH data AS ("
+            " SELECT a.* "
+            " FROM  __relations_temp a LEFT JOIN " +  addSchema("osm_relations") + " b USING (relation_id, type_id, class_id)"
+            "     WHERE (b.relation_id IS NULL OR b.type_id IS NULL OR b.class_id IS NULL))"
+
+            " INSERT INTO " + addSchema("osm_relations")  + " "
+            "(" + relations_columns + ") "
+            " (SELECT " + relations_columns + " FROM data); ");
     q_result = PQexec(mycon, insert_into_relations.c_str());
-    std::cout << " Inserted: " << PQcmdTuples(q_result) << "\n";
+    if (PQresultStatus(q_result) != PGRES_COMMAND_OK) {
+        std::cerr << PQresultStatus(q_result);
+        std::cerr << "Inserting to osm_relations failed \n"
+            << PQerrorMessage(mycon)
+            << std::endl;
+    } else {
+        std::cout << "\tInserted: " << PQcmdTuples(q_result) << " in " << addSchema("osm_relations") << "\n";
+    }
+
     PQclear(q_result);
     dropTable("__relations_temp");
 }
 
 
-//////////should break into 2 functions
+// ////////should break into 2 functions
 
-void Export2DB::exportRelationsWays(const std::vector<Relation*> &relations/*, Configuration *config*/) const {
+void Export2DB::exportRelationsWays(const std::vector<Relation> &relations, const Configuration &config) const {
     std::cout << "    Processing way's relations: ";
-    createTempTable( create_relations_ways, "__relations_ways_temp" );
-    
-    std::string relations_ways_columns(" relation_id, way_id " );   
-    std::string copy_relations_ways( "COPY __relations_ways_temp (" + relations_ways_columns + ") FROM STDIN");
+    createTempTable(create_relations_ways, "__relations_ways_temp");
+
+    std::string relations_ways_columns(" relation_id, way_id, type ");
+    std::string copy_relations_ways("COPY __relations_ways_temp (" + relations_ways_columns + ") FROM STDIN");
     PGresult* q_result = PQexec(mycon, copy_relations_ways.c_str());
 
 
-    for (const auto &relation : relations) {
-        for (const auto &way_id : relation->m_WayRefs) {
-            std::string row_data = TO_STR(relation->id);
+    for (auto it = relations.begin(); it != relations.end(); ++it) {
+        auto relation = *it;
+        for (auto it_ref = relation.way_refs().begin(); it_ref != relation.way_refs().end(); ++it_ref) {
+            auto way_id = *it_ref;
+            std::string row_data = TO_STR(relation.osm_id());
             row_data += "\t";
             row_data += TO_STR(way_id);
+            row_data += "\t";
+            row_data += TO_STR(config.FindType(relation.tag_config().key()).id());
             row_data += "\n";
             PQputline(mycon, row_data.c_str());
         }
@@ -513,52 +552,52 @@ void Export2DB::exportRelationsWays(const std::vector<Relation*> &relations/*, C
     PQclear(q_result);
 
     std::string insert_into_relations_ways(
-         " WITH data AS ( "
-         " SELECT a.* "
-         " FROM  __relations_ways_temp a LEFT JOIN " + addSchema( full_table_name("relations_ways") ) + " b USING (relation_id, way_id)"
-         "     WHERE (b.relation_id IS NULL OR b.way_id IS NULL))"
+            " WITH data AS ("
+            " SELECT a.* "
+            " FROM  __relations_ways_temp a LEFT JOIN " + addSchema(full_table_name("relations_ways")) + " b USING (relation_id, way_id)"
+            "     WHERE (b.relation_id IS NULL OR b.way_id IS NULL))"
 
-         " INSERT INTO " + addSchema( full_table_name("relations_ways") ) +
-         " SELECT * FROM data; ");
+            " INSERT INTO " + addSchema(full_table_name("relations_ways")) +
+            " SELECT * FROM data; ");
     q_result = PQexec(mycon, insert_into_relations_ways.c_str());
-    std::cout << " Inserted: " << PQcmdTuples(q_result) << "way's relations\n" ;
+    std::cout << "\t Inserted: " << PQcmdTuples(q_result) << " in " << addSchema(full_table_name("relations_ways")) << "\n";
     PQclear(q_result);
     dropTable("__relations_ways_temp");
-
 }
 
 
 
 /*
-<relation id="147411" version="5" timestamp="2010-01-22T17:02:14Z" uid="24299" user="james_hiebert" changeset="3684904">
-    <member type="way" ref="25584788" role=""/>
-    <member type="way" ref="35064036" role=""/>
-    <member type="way" ref="35064035" role=""/>
-    <member type="way" ref="35064037" role=""/>
-    <member type="way" ref="35064038" role=""/>
-    <member type="way" ref="35065746" role=""/>
-    <member type="way" ref="48690404" role=""/>
-    <member type="way" ref="24221632" role=""/>
-    <tag k="name" v="Mt. Douglas Park Local Connector"/>
-    <tag k="network" v="rcn"/>
-    <tag k="route" v="bicycle"/>
-    <tag k="type" v="route"/>
-  </relation>
- */
-
-void Export2DB::exportTags(const std::vector<Way*> &ways, Configuration *config) const
-{
+   <relation id="147411" version="5" timestamp="2010-01-22T17:02:14Z" uid="24299" user="james_hiebert" changeset="3684904">
+   <member type="way" ref="25584788" role=""/>
+   <member type="way" ref="35064036" role=""/>
+   <member type="way" ref="35064035" role=""/>
+   <member type="way" ref="35064037" role=""/>
+   <member type="way" ref="35064038" role=""/>
+   <member type="way" ref="35065746" role=""/>
+   <member type="way" ref="48690404" role=""/>
+   <member type="way" ref="24221632" role=""/>
+   <tag k="name" v="Mt. Douglas Park Local Connector"/>
+   <tag k="network" v="rcn"/>
+   <tag k="route" v="bicycle"/>
+   <tag k="type" v="route"/>
+   </relation>
+   */
+
+void Export2DB::exportTags(const std::map<int64_t, Way> &ways, const Configuration &config) const {
     std::cout << "    Processing way's tags"  << ": ";
 
-    createTempTable( create_way_tag, "__way_tag_temp"); 
-    std::string copy_way_tag( "COPY  __way_tag_temp (class_id, way_id) FROM STDIN");
+    createTempTable(create_way_tag, "__way_tag_temp");
+    std::string copy_way_tag("COPY  __way_tag_temp (class_id, way_id) FROM STDIN");
     PGresult* q_result = PQexec(mycon, copy_way_tag.c_str());
-    
-    for (const auto &way : ways) {
-        for (const auto &tag : way->m_Tags) {
-            std::string row_data = TO_STR(config->FindClass(tag.first, tag.second)->id);
+
+    for (auto it = ways.begin(); it != ways.end(); ++it) {
+        auto way = it->second;
+        for (auto it_tag = way.tags().begin(); it_tag != way.tags().end(); ++it_tag) {
+            auto tag = *it_tag;
+            std::string row_data = TO_STR(config.FindClass(Tag(tag.first, tag.second)).id());
             row_data += "\t";
-            row_data += TO_STR(way->id);
+            row_data += TO_STR(way.osm_id());
             row_data += "\n";
             PQputline(mycon, row_data.c_str());
         }
@@ -568,16 +607,16 @@ void Export2DB::exportTags(const std::vector<Way*> &ways, Configuration *config)
     PQclear(q_result);
 
     std::string insert_into_tags(
-         " WITH data AS ( "
-         " SELECT a.class_id, a.way_id "
-         " FROM  __way_tag_temp a LEFT JOIN  " +  addSchema( "osm_way_tags" ) + " b USING ( class_id, way_id ) "
-         "     WHERE ( b.class_id IS NULL OR b.way_id IS NULL))"
+            " WITH data AS ("
+            " SELECT a.class_id, a.way_id "
+            " FROM  __way_tag_temp a LEFT JOIN  " +  addSchema("osm_way_tags") + " b USING (class_id, way_id) "
+            "     WHERE (b.class_id IS NULL OR b.way_id IS NULL))"
 
-         " INSERT INTO " +  addSchema( "osm_way_tags" ) +
-         " SELECT * FROM data; ");
+            " INSERT INTO " +  addSchema("osm_way_tags") +
+            " SELECT * FROM data; ");
 
     q_result = PQexec(mycon, insert_into_tags.c_str());
-    std::cout << " Inserted " << PQcmdTuples(q_result) << " way's tags\n";
+    std::cout << "\t Inserted: " << PQcmdTuples(q_result) << " in " << addSchema("osm_way_tags") << "\n";
     PQclear(q_result);
 
     dropTable("__way_tag_temp");
@@ -585,146 +624,170 @@ void Export2DB::exportTags(const std::vector<Way*> &ways, Configuration *config)
 
 
 void Export2DB::prepare_table(const std::string &ways_columns) const {
-    if (createTempTable( create_ways, "__ways_temp") )
-        addTempGeometry( "__ways_temp", "LINESTRING" );
+    if (createTempTable(create_ways, "__ways_temp")) {
+        addTempGeometry("__ways_temp", "LINESTRING");
+    } else {
+        std::cerr << "could not createTempTable\n";
+    }
+
+    std::string copy_ways("COPY __ways_temp  ("
+            + ways_columns
+            + ") FROM STDIN");
 
-    std::string copy_ways( "COPY __ways_temp  ("
-                    + ways_columns
-                    + " ) FROM STDIN");
     PGresult* q_result = PQexec(mycon, copy_ways.c_str());
     PQclear(q_result);
 }
 
-void Export2DB::exportWays(const std::vector<Way*> &ways, Configuration *config) const {
-
+void Export2DB::exportWays(const std::map<int64_t, Way> &ways, const Configuration &config) const {
     std::cout << "    Processing " <<  ways.size() <<  " ways"  << ":\n";
 
+    std::string separator("\t");
     std::string ways_columns(
-                     " class_id, length,"
-                     " x1, y1,"
-                     " x2, y2,"
-                     " osm_id, source_osm," " target_osm,"
-                     " the_geom,"
-                     " cost, reverse_cost,"
-                     " one_way,"
-                     " maxspeed_forward, maxspeed_backward,"
-                     " priority,"
-                     " name");
+            " class_id, "
+            " osm_id, "
+            " maxspeed_forward, maxspeed_backward, "
+            " one_way, "
+            " priority, "
+
+            " length,"
+            " x1, y1,"
+            " x2, y2,"
+            " source_osm,"
+            " target_osm,"
+            " the_geom,"
+            " cost, "
+            " reverse_cost,"
+
+            " name ");
+
     prepare_table(ways_columns);
 
+    uint32_t chunck_size = 20000;
     int64_t count = 0;
-    for (const auto &way : ways) {
-	if ((++count % 100000) == 0) {
+    int64_t split_count = 0;
+    for (auto it = ways.begin(); it != ways.end(); ++it) {
+        auto way = it->second;
+
+        // std::cout << way << "\n";
+        if ((count % (chunck_size / 100)) == 0) {
+            print_progress(ways.size(), count);
+        }
+        ++count;
+        if (way.tag_config().key() == "" || way.tag_config().value() == "") continue;
+
+        if ((count % chunck_size) == 0) {
             PQputline(mycon, "\\.\n");
             PQendcopy(mycon);
-            process_section(count, ways_columns);
+            std::cout << "    Ways Processed: " << count << "\t";
+            std::cout << "    Split Ways generated: " << split_count << "\t";
+            process_section(ways_columns);
+            split_count = 0;
             prepare_table(ways_columns);
         }
-        std::string row_data = TO_STR(config->FindClass(way->type, way->clss)->id);
-        row_data += "\t";
-        row_data += TO_STR(way->length);
-        row_data += "\t";
-        row_data += TO_STR(way->m_NodeRefs.front()->lon);
-        row_data += "\t";
-        row_data += TO_STR(way->m_NodeRefs.front()->lat);
-        row_data += "\t";
-        row_data += TO_STR(way->m_NodeRefs.back()->lon);
-        row_data += "\t";
-        row_data += TO_STR(way->m_NodeRefs.back()->lat);
-        row_data += "\t";
-        row_data += TO_STR(way->osm_id);
-        row_data += "\t";
-        row_data += TO_STR(way->m_NodeRefs.front()->id);
-        row_data += "\t";
-        row_data += TO_STR(way->m_NodeRefs.back()->id);
-        row_data += "\t";
-        row_data += "srid=4326;" + way->geom;
-        row_data += "\t";
-
-        //cost based on oneway
-        if(way->oneWayType==REVERSED)
-            row_data += TO_STR(- way->length);
-        else
-            row_data += TO_STR(way->length);
-        //reverse_cost
-        row_data += "\t";
-        if(way->oneWayType==YES)
-                row_data += TO_STR(- way->length);
-        else
-            row_data += TO_STR(way->length);
-
-        row_data += "\t";
-        row_data += TO_STR(way->oneWayType);
-        row_data += "\t";
-
-        //maxspeed
-        row_data += TO_STR(way->maxspeed_forward);
-        row_data += "\t";
-        row_data += TO_STR(way->maxspeed_backward);
-        row_data += "\t";
 
-        //priority
-        row_data += TO_STR(config->FindClass(way->type,way->clss)->priority);
-        row_data += "\t";
-
-        //name
-          if(!way->name.empty())
-          {
-            std::string escaped_name = way->name;
+        // common information of the split ways
+        auto way_data =
+            TO_STR(config.FindClass(way.tag_config()).id())  + "\t"
+            + TO_STR(way.osm_id()) + "\t"
+            // maxspeed
+            + way.maxspeed_forward_str() + "\t"
+            + way.maxspeed_backward_str() + "\t"
+            // one_way
+            + way.oneWayType_str() + "\t"
+            // priority
+            + config.priority_str(way.tag_config()) + "\t";
+
+        // name
+        std::string name_data;
+        if (!way.name().empty()) {
+            std::string escaped_name = way.name();
             boost::replace_all(escaped_name, "\\", "");
             boost::replace_all(escaped_name, "\t", "\\\t");
             boost::replace_all(escaped_name, "\n", "");
             boost::replace_all(escaped_name, "\r", "");
-            row_data += escaped_name.substr(0,199);
-          }
-        row_data += "\n";
+            name_data = escaped_name.substr(0, 199);
+        }
 
-        PQputline(mycon, row_data.c_str());
+        auto splits = way.split_me();
+        split_count +=  splits.size();
+
+        for (size_t i = 0; i < splits.size(); ++i) {
+            auto length = way.length_str(splits[i]);
+
+            // length (degrees)
+            auto split_data = length + "\t"
+                // x1, y1
+                + splits[i].front()->geom_str("\t") + "\t"
+                // x2, y2
+                + splits[i].back()->geom_str("\t") + "\t"
+                // source_osm
+                + TO_STR(splits[i].front()->osm_id()) + "\t"
+                // target_osm
+                + TO_STR(splits[i].back()->osm_id()) + "\t"
+                // geometry
+                + "srid=4326;" + way.geometry_str(splits[i]) + "\t";
+
+            // cost based on oneway
+            if (way.is_reversed())
+                split_data += "-" + length;
+            else
+                split_data += length;
+            split_data += "\t";
+
+            // reverse_cost
+            if (way.is_oneway())
+                split_data += "-" + length;
+            else
+                split_data += length;
+            split_data += "\t";
+
+            split_data =  way_data + split_data + name_data + "\n";
+            PQputline(mycon, split_data.c_str());
+        }
     }
     PQputline(mycon, "\\.\n");
     PQendcopy(mycon);
-    process_section(count, ways_columns);
+    std::cout << "    Ways Processed: " << count << "\t";
+    std::cout << "    Split Ways generated: " << split_count << "\t";
+    process_section(ways_columns);
 }
 
-void Export2DB::process_section(int64_t count, const std::string &ways_columns) const{
+void Export2DB::process_section(const std::string &ways_columns) const {
+    auto ways_name = full_table_name("ways");
+    auto vertices_name = ways_name + "_vertices_pgr";
 
+    //  std::cout << "Creating indices in temporary table\n";
+    create_gindex("__ways_temp", "__ways_temp");
+    create_idindex("source_osm", "__ways_temp");
+    create_idindex("target_osm", "__ways_temp");
 
-    // std::cout << "Creating indices in temporary table\n";
-    create_gindex( "__ways_temp", "__ways_temp");
-    create_idindex(  "source_osm", "__ways_temp");
-    create_idindex(  "target_osm", "__ways_temp");
-#if 0
-    create_idindex(  "source", "__ways_temp" );
-    create_idindex(  "target", "__ways_temp" );
-#endif
-
-    // std::cout << "Deleting  duplicated ways from temporary table\n";
+    //  std::cout << "Deleting  duplicated ways from temporary table\n";
     std::string delete_from_temp(
-         " DELETE FROM __ways_temp a "
-         "     USING " + addSchema( full_table_name("ways") ) + " b "
-         "     WHERE a.the_geom ~= b.the_geom AND ST_OrderingEquals(a.the_geom, b.the_geom);");
+            " DELETE FROM __ways_temp a "
+            "     USING " + addSchema(ways_name) + " b "
+            "     WHERE a.the_geom ~= b.the_geom AND ST_OrderingEquals(a.the_geom, b.the_geom);");
+
     PGresult* q_result = PQexec(mycon, delete_from_temp.c_str());
-    // std::cout << "     Deleted " << PQcmdTuples(q_result) << " duplicated ways from temporary table\n";
+    //  std::cout << "     Deleted " << PQcmdTuples(q_result) << " duplicated ways from temporary table\n";
     PQclear(q_result);
 
-    // std::cout << "Updating to existing toplology the temporary table\n";
-    fill_source_target( "__ways_temp" , addSchema( full_table_name("ways_vertices_pgr") ) );
+    //  std::cout << "Updating to existing toplology the temporary table\n";
+    fill_source_target("__ways_temp" , addSchema(vertices_name));
 
-    // std::cout << "Inserting new vertices in the vertex table\n";
-    fill_vertices_table(  "__ways_temp" , addSchema( full_table_name("ways_vertices_pgr") ) );
+    //  std::cout << "Inserting new vertices in the vertex table\n";
+    fill_vertices_table("__ways_temp" , addSchema(vertices_name));
 
-    // std::cout << "Updating to new toplology the temporary table\n";
-    fill_source_target( "__ways_temp" , addSchema( full_table_name("ways_vertices_pgr") ) );
+    //  std::cout << "Updating to new toplology the temporary table\n";
+    fill_source_target("__ways_temp" , addSchema(vertices_name));
 
 
-    // std::cout << "Inserting new splitted ways to '" << addSchema( full_table_name("ways") ) << "'\n";
+    //  std::cout << "Inserting new split ways to '" << addSchema(full_table_name("ways")) << "'\n";
     std::string insert_into_ways(
-         " INSERT INTO " + addSchema( full_table_name("ways") ) +
-          "( " + ways_columns + ", source, target, length_m, cost_s, reverse_cost_s ) "
-         " (SELECT " + ways_columns + ", source, target, length_m, cost_s, reverse_cost_s FROM __ways_temp); ");
+            " INSERT INTO " + addSchema(ways_name) +
+            "(" + ways_columns + ", source, target, length_m, cost_s, reverse_cost_s) "
+            " (SELECT " + ways_columns + ", source, target, length_m, cost_s, reverse_cost_s FROM __ways_temp); ");
     q_result = PQexec(mycon, insert_into_ways.c_str());
-    // std::cout << " Inserted " << PQcmdTuples(q_result) << " splitted ways\n";
-    std::cout << "    Ways inserted: " << count << "\n";
+    std::cout << " Inserted " << PQcmdTuples(q_result) << " split ways\n";
     PQclear(q_result);
     dropTable("__ways_temp");
 }
@@ -735,21 +798,20 @@ void Export2DB::process_section(int64_t count, const std::string &ways_columns)
 
 
 
-void Export2DB::exportTypes(const std::map<std::string, Type*> &types)  const
-{
+void Export2DB::exportTypes(const std::map<std::string, Type> &types)  const {
     std::cout << "    Processing " << types.size() << " way types: ";
 
-    createTempTable( create_types, "__way_types_temp"); 
-    std::string copy_types( "COPY __way_types_temp ( type_id, name ) FROM STDIN");
+    createTempTable(create_types, "__way_types_temp");
+    std::string copy_types("COPY __way_types_temp (type_id, name) FROM STDIN");
 
     PGresult* q_result = PQexec(mycon, copy_types.c_str());
 
-    for ( const auto &e : types)
-    {
-        Type* type = e.second;
-        std::string row_data = TO_STR(type->id);
+    for (auto it = types.begin(); it != types.end(); ++it) {
+        auto e = *it;
+        auto type = e.second;
+        std::string row_data = TO_STR(type.id());
         row_data += "\t";
-        row_data += type->name;
+        row_data += type.name();
         row_data += "\n";
         PQputline(mycon, row_data.c_str());
     }
@@ -758,16 +820,16 @@ void Export2DB::exportTypes(const std::map<std::string, Type*> &types)  const
     PQclear(q_result);
 
     std::string insert_into_types(
-         " WITH data AS ( "
-         " SELECT a.* "
-         " FROM  __way_types_temp a LEFT JOIN  " + addSchema("osm_way_types") + " b USING ( type_id ) "
-         "     WHERE (b.type_id IS NULL))"
+            " WITH data AS ("
+            " SELECT a.* "
+            " FROM  __way_types_temp a LEFT JOIN  " + addSchema("osm_way_types") + " b USING (type_id) "
+            "     WHERE (b.type_id IS NULL))"
 
-         " INSERT INTO "  + addSchema( "osm_way_types" ) + " ( type_id, name ) "
-         " (SELECT *  FROM data); ");
+            " INSERT INTO "  + addSchema("osm_way_types") + " (type_id, name) "
+            " (SELECT *  FROM data); ");
 
     q_result = PQexec(mycon, insert_into_types.c_str());
-    std::cout << " Inserted " << PQcmdTuples(q_result) << " way types\n";
+    std::cout << "\t Inserted: " << PQcmdTuples(q_result) << " in " << addSchema("osm_way_types") << "\n";
 
     PQclear(q_result);
     dropTable("__way_types_temp");
@@ -778,31 +840,33 @@ void Export2DB::exportTypes(const std::map<std::string, Type*> &types)  const
 
 
 
-void Export2DB::exportClasses(const std::map<std::string, Type*> &types)  const {
+void Export2DB::exportClasses(const std::map<std::string, Type> &types)  const {
     std::cout << "    Processing way's classes: ";
 
     std::string copy_classes(
-            "COPY __classes_temp"   
+            "COPY __classes_temp"
             "   (class_id, type_id, name, priority, default_maxspeed)"
             "   FROM STDIN");
 
-    createTempTable( create_classes, "__classes_temp" );
+    createTempTable(create_classes, "__classes_temp");
     PGresult *q_result = PQexec(mycon, copy_classes.c_str());
 
-    for ( const auto &t : types) {
-        Type type(*t.second);
+    for (auto it = types.begin(); it != types.end(); ++it) {
+        auto t = *it;
+        auto type(t.second);
 
-        for (const auto &c : type.m_Classes ) {
-            Class clss(*c.second);
-            std::string row_data = TO_STR(clss.id);
+        for (auto it_c = type.classes().begin(); it_c != type.classes().end(); ++it_c) {
+            auto c = *it_c;
+            Class clss(c.second);
+            std::string row_data = TO_STR(clss.id());
             row_data += "\t";
-            row_data += TO_STR(type.id);
+            row_data += TO_STR(type.id());
             row_data += "\t";
-            row_data += clss.name;
+            row_data += clss.name();
             row_data += "\t";
-            row_data += TO_STR(clss.priority);
+            row_data += TO_STR(clss.priority());
             row_data += "\t";
-            row_data += TO_STR(clss.default_maxspeed);
+            row_data += TO_STR(clss.default_maxspeed());
             row_data += "\n";
             PQputline(mycon, row_data.c_str());
         }
@@ -812,24 +876,69 @@ void Export2DB::exportClasses(const std::map<std::string, Type*> &types)  const
     PQclear(q_result);
 
     std::string insert_into_classes(
-         " WITH data AS ( "
-         " SELECT a.* "
-         " FROM  __classes_temp a LEFT JOIN " + addSchema( "osm_way_classes" ) + " b USING ( class_id ) "
-         "     WHERE (b.class_id IS NULL))"
+            " WITH data AS ("
+            " SELECT a.* "
+            " FROM  __classes_temp a LEFT JOIN " + addSchema("osm_way_classes") + " b USING (class_id) "
+            "     WHERE (b.class_id IS NULL))"
 
-         " INSERT INTO " + addSchema( "osm_way_classes" ) + 
-         " SELECT *  FROM data; ");
+            " INSERT INTO " + addSchema("osm_way_classes") +
+            " SELECT *  FROM data; ");
 
     q_result = PQexec(mycon, insert_into_classes.c_str());
-    std::cout << " Inserted " << PQcmdTuples(q_result) << " way's classes\n";
+    std::cout << "\t Inserted: " << PQcmdTuples(q_result) << " in " << addSchema("osm_way_classes") << "\n";
 
     PQclear(q_result);
     dropTable("__classes_temp");
 }
 
-void Export2DB::createTopology() const
-{
-    //fill_source_target( full_table_name( "ways" ), full_table_name("ways") + "_vertices_pgr");
-    //fill_vertices_table( full_table_name( "ways" ), full_table_name( "nodes" ) );
-    //fill_source_target( full_table_name( "ways" ) );
+
+void Export2DB::createFKeys() {
+    auto ways_name = full_table_name("ways");
+    auto vertices_name = ways_name + "_vertices_pgr";
+
+
+    std::string fk_classes(
+            "ALTER TABLE " + addSchema("osm_way_classes")  + " ADD  FOREIGN KEY (type_id) REFERENCES " +  addSchema("osm_way_types")  + "(type_id)");
+    PGresult *result = PQexec(mycon, fk_classes.c_str());
+    if (PQresultStatus(result) != PGRES_COMMAND_OK) {
+        std::cerr << PQresultStatus(result);
+        std::cerr << "foreign keys for " + addSchema("osm_way_classes")  + " failed:"
+            << PQerrorMessage(mycon)
+            << std::endl;
+        PQclear(result);
+    } else {
+        std::cout << "Foreign keys for " + addSchema("osm_way_classes")  + " table created" << std::endl;
+    }
+
+
+    std::string fk_relations(
+            "ALTER TABLE " + addSchema(full_table_name("relations_ways"))  + " ADD FOREIGN KEY (relation_id) REFERENCES " + addSchema("osm_relations") + "(relation_id); ");
+    result = PQexec(mycon, fk_relations.c_str());
+    if (PQresultStatus(result) != PGRES_COMMAND_OK) {
+        std::cerr << PQresultStatus(result);
+        std::cerr << "foreign keys for " + addSchema(full_table_name("relations_ways"))  + " failed: "
+            << PQerrorMessage(mycon)
+            << std::endl;
+        PQclear(result);
+    } else {
+        std::cout << "Foreign keys for " + addSchema(full_table_name("relations_ways"))  + " table created" << std::endl;
+    }
+
+    std::string fk_ways(
+            "ALTER TABLE " + addSchema(ways_name) + " ADD FOREIGN KEY (class_id) REFERENCES " + addSchema("osm_way_classes") + "(class_id);" +
+            "ALTER TABLE " + addSchema(ways_name) + " ADD FOREIGN KEY (source) REFERENCES " + addSchema(vertices_name) + "(id); " +
+            "ALTER TABLE " + addSchema(ways_name) + " ADD FOREIGN KEY (target) REFERENCES " + addSchema(vertices_name) + "(id);");
+    result = PQexec(mycon, fk_ways.c_str());
+
+    if (PQresultStatus(result) != PGRES_COMMAND_OK) {
+        std::cerr << PQresultStatus(result);
+        std::cerr << "foreign keys for ways failed: "
+            << PQerrorMessage(mycon)
+            << std::endl;
+        PQclear(result);
+    } else {
+        std::cout << "Foreign keys for Ways table created" << std::endl;
+    }
 }
+
+}  // namespace osm2pgr
diff --git a/src/Export2DB.h b/src/Export2DB.h
index 47b9c01..8924542 100644
--- a/src/Export2DB.h
+++ b/src/Export2DB.h
@@ -1,6 +1,6 @@
 /***************************************************************************
- *   Copyright (C) 2008 by Daniel Wendt   								   *
- *   gentoo.murray at gmail.com   											   *
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -10,7 +10,7 @@
  *   This program is distributed in the hope that it will be useful,       *
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
+ *   GNU General Public License t &or more details.                        *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
@@ -18,132 +18,143 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
-#ifndef EXPORT2DB_H
-#define EXPORT2DB_H
-
-#if 1  // Nagase San code
-#include "libpq-fe.h"
-#else  // Code we were using temporarly
-#ifdef __MINGW32__
-#include "libpq-fe.h"
-#else
-#include "postgresql/libpq-fe.h"
-#endif
-#endif
-
-#include "Node.h"
-#include "Way.h"
-#include "Relation.h"
-#include "Type.h"
-#include "Class.h"
-#include "Configuration.h"
-#include "prog_options.h"
- 
-using namespace osm2pgr;
+
+#ifndef SRC_EXPORT2DB_H_
+#define SRC_EXPORT2DB_H_
+
+#include <libpq-fe.h>
+#include <map>
+#include <vector>
+#include <string>
+
+#include "./Node.h"
+#include "./Way.h"
+#include "./Relation.h"
+#include "./Type.h"
+#include "./Class.h"
+#include "./Configuration.h"
+#include "./prog_options.h"
+
+namespace osm2pgr {
 
 /**
  * This class connects to a postgresql database. For using this class,
  * you also need to install postgis and pgrouting
  */
 
-class Export2DB
-{
-public:
-	/**
-	 * Construktor
-	 * @param host Host address of the database
-	 * @param user a user, who has write access to the database
-	 * @param dbname name of the database
-	 *
-	 */
- 	Export2DB(const  po::variables_map &vm);
- 	
- 	/**
- 	 * Destructor
- 	 * closes the connection to the database
- 	 */
- 	~Export2DB();
-
- 	//! connects to database
- 	int connect();
-    bool has_postGIS() const;
-
- 	//! creates needed tables and geometries
- 	void createTables() const;
- 	void createTempTables() const;
- 	//! exports nodes to the database
- 	void exportNodes(const std::map<long long, Node*>& nodes) const;
- 	//! exports ways to the database
- 	void exportTags(const std::vector<Way*> &ways, Configuration *config) const;
- 	void exportRelations(const std::vector<Relation*> &relations, Configuration *config) const;
- 	void exportRelationsWays(const std::vector<Relation*> &relations/*, Configuration *config*/) const;
- 	void exportTypes(const std::map<std::string, Type*>& types) const;
- 	void exportClasses(const std::map<std::string, Type*>& types) const;
- 	void exportWays(const std::vector<Way*> &ways, Configuration *config) const;
-
- 	/**
- 	 * creates the topology
- 	 * Be careful, it takes some time.
- 	 *
- 	 * for example:
- 	 * complete germany: OSM file with a size of 1,1 GiB.
- 	 * Export and create topology:
- 	 * time took circa 30 hours on an Intel Xeon 2,4 GHz with 2 GiB Ram.
- 	 * But only for the streettypes "motorway", "primary" and "secondary"
- 	 */
- 	void createTopology() const;
- 	//! Be careful! It deletes the created tables!
- 	void dropTables() const;
- 	void dropTempTables() const;
+class Export2DB {
+ public:
+     /**
+      * Constructor 
+      * @param vm variable map holding the configuration
+      *
+      */
+     explicit Export2DB(const po::variables_map &vm);
+
+     /**
+      * Destructor
+      * closes the connection to the database
+      */
+     ~Export2DB();
+
+     //! connects to database
+     int connect();
+     bool has_postGIS() const;
+
+     //! creates needed tables and geometries
+     void createTables() const;
+     void createTempTables() const;
+     //! exports nodes to the database
+     void prepareExportNodes(const std::string nodes_columns) const;
+     void exportNodes(const std::map<int64_t, Node>& nodes) const;
+     void processSectionExportNodes(const std::string nodes_columns) const;
+
+     //! exports ways to the database
+     void exportTags(
+             const std::map<int64_t, Way> &ways,
+             const Configuration &config) const;
+     void exportRelations(
+             const std::vector<Relation> &relations,
+             const Configuration &config) const;
+     void exportRelationsWays(
+             const std::vector<Relation> &relations,
+             const Configuration &config) const;
+     void exportTypes(const std::map<std::string, Type>& types) const;
+     void exportClasses(const std::map<std::string, Type>& types) const;
+     void exportWays(
+             const std::map<int64_t, Way> &ways,
+             const Configuration &config) const;
+
+     //! Be careful! It deletes the created tables!
+     void dropTables() const;
+     void dropTempTables() const;
+     void createFKeys();
+
+ private:
+     //! to use with creating the ways
+     void prepare_table(const std::string &ways_columns) const;
+     void process_section(const std::string &ways_columns) const;
+
+     void dropTempTable(
+             const std::string &table) const;
+     bool createTempTable(
+             const std::string &sql,
+             const std::string &table) const;
+     void dropTable(const std::string &table) const;
+     bool createTempTable(
+             const std::string &sql,
+             const std::string &table);
+     bool createTable(
+             const std::string &sql,
+             const std::string &table,
+             const std::string &constraint = std::string("")) const;
+     void addTempGeometry(
+             const std::string &table,
+             const std::string &geometry_type) const;
+     void addGeometry(
+             const std::string &schema,
+             const std::string &table,
+             const std::string &geometry_type) const;
+     void create_gindex(
+             const std::string &index,
+             const std::string &table) const;
+     void create_idindex(
+             const std::string &colname,
+             const std::string &table) const;
+     inline std::string full_table_name(const std::string &table) const {
+         return tables_prefix + table + tables_suffix;
+     }
+     inline std::string addSchema(const std::string &table) const {
+         return  (default_tables_schema() == "" ? ""
+                 : default_tables_schema() + ".") + table;
+     }
+     inline std::string default_tables_schema() const {
+         return tables_schema;
+     }
+     void fill_vertices_table(
+             const std::string &table,
+             const std::string &vertices_tab) const;
+     void fill_source_target(
+             const std::string &table,
+             const std::string &vertices_tab) const;
 
  private:
-    //! to use with creating the ways
-    void prepare_table(const std::string &ways_columns) const;
-    void process_section(int64_t count, const std::string &ways_columns) const;
-
-    void dropTempTable(const std::string &table) const;
-    bool createTempTable(const std::string &sql,
-			 const std::string &table) const;
-    void dropTable(const std::string &table) const;
-    bool createTempTable(const std::string &sql,
-			 const std::string &table);
-    bool createTable(const std::string &sql,
-			 const std::string &table,
-			 const std::string &constraint = std::string("")) const;
-    void addTempGeometry( const std::string &table,
-                         const std::string &geometry_type) const;
-    void addGeometry( const std::string &schema, const std::string &table,
-                         const std::string &geometry_type) const;
-    void create_gindex(const std::string &index, const std::string &table) const;
-    void create_idindex(const std::string &colname, const std::string &table) const;
-    inline std::string full_table_name(const std::string &table) const {
-		return tables_prefix + table + tables_suffix;
-        }
-    inline std::string addSchema(const std::string &table) const {
-        return  (default_tables_schema() == "" ? "" : default_tables_schema() + ".") + table;
-        }
-    inline std::string default_tables_schema() const {
-		return tables_schema;
-        }
-	void fill_vertices_table(const std::string &table, const std::string &vertices_tab) const;
-	void fill_source_target(const std::string &table, const std::string &vertices_tab) const;
-
-private:
-	PGconn *mycon;
-	std::string conninf;
-	std::string tables_schema;
-	std::string tables_prefix;
-	std::string tables_suffix;
-
-        // create table query constants
-	std::string create_classes;
-	std::string create_nodes;
-	std::string create_ways;
-	std::string create_relations;
-	std::string create_relations_ways;
-	std::string create_way_tag;
-	std::string create_types;
-	std::string create_vertices;
+     PGconn *mycon;
+     std::string conninf;
+     std::string tables_schema;
+     std::string tables_prefix;
+     std::string tables_suffix;
+
+     // create table query constants
+     std::string create_classes;
+     std::string create_nodes;
+     std::string create_ways;
+     std::string create_relations;
+     std::string create_relations_ways;
+     std::string create_way_tag;
+     std::string create_types;
+     std::string create_vertices;
 };
+}  // namespace osm2pgr
 
-#endif
+#endif  // SRC_EXPORT2DB_H_
diff --git a/src/Node.cpp b/src/Node.cpp
index 256cf94..d24ba4e 100644
--- a/src/Node.cpp
+++ b/src/Node.cpp
@@ -1,6 +1,6 @@
 /***************************************************************************
- *   Copyright (C) 2008 by Daniel Wendt   								   *
- *   gentoo.murray at gmail.com   											   *
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -10,7 +10,7 @@
  *   This program is distributed in the hope that it will be useful,       *
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
+ *   GNU General Public License t &or more details.                        *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
@@ -18,16 +18,53 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
+
+#if 0
+#include <boost/geometry.hpp>
+#include <boost/geometry/geometries/point_xy.hpp>
+#endif
+
+#include <boost/lexical_cast.hpp>
+#include <map>
+#include <cassert>
+#include <math.h>
+#include "./osm_tag.h"
 #include "./Node.h"
 
 namespace osm2pgr {
 
-Node::Node(int64_t id, double lat, double lon) :
-    id(id),
-    lat(lat),
-    lon(lon) {
-    this->numsOfUse = 0;
-}
 
+Node::Node(const char **atts) :
+    Element(atts),
+    m_numsOfUse(0) {
+        assert(has_attribute("lat"));
+        assert(has_attribute("lon"));
+    }
+
+
+double
+Node::getLength(const Node &previous) const {
+     auto y1 = boost::lexical_cast<double>(get_attribute("lat"));
+     auto x1 = boost::lexical_cast<double>(get_attribute("lon"));
+     auto y2 = boost::lexical_cast<double>(previous.get_attribute("lat"));
+     auto x2 = boost::lexical_cast<double>(previous.get_attribute("lon"));
+     return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
+#if 0
+    typedef boost::geometry::model::d2::point_xy<double> point_type;
+
+    /* converted point to fit boost.geomtery
+     *      * (`p` and `q` are same as `a ` and `b`)
+     *           */
+    point_type p(
+            boost::lexical_cast<double>(get_attribute("lat")),
+            boost::lexical_cast<double>(get_attribute("lon")));
+
+    point_type q(
+            boost::lexical_cast<double>(previous.get_attribute("lat")),
+            boost::lexical_cast<double>(previous.get_attribute("lon")));
+
+    return boost::geometry::distance(p, q);
+#endif
+}
 
-}  // end namespace osm2pgr
+}  // namespace osm2pgr
diff --git a/src/Node.h b/src/Node.h
index be6246d..24e6aaa 100644
--- a/src/Node.h
+++ b/src/Node.h
@@ -1,6 +1,6 @@
 /***************************************************************************
- *   Copyright (C) 2008 by Daniel Wendt       							   *
- *   gentoo.murray at gmail.com   											   *
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -10,7 +10,7 @@
  *   This program is distributed in the hope that it will be useful,       *
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
+ *   GNU General Public License t &or more details.                        *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
@@ -18,40 +18,79 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
+
 #ifndef SRC_NODE_H_
 #define SRC_NODE_H_
+#pragma once
+
+#include <boost/lexical_cast.hpp>
 #include <cstdint>
+#include <string>
+#include <map>
+#include "./osm_element.h"
 
 namespace osm2pgr {
 
-/**
-\code
-  <node id="122603925" 
-		lat="53.0780875" 
-		lon="8.1351704" 
-		user="artus70" visible="true" timestamp="2007-11-18T22:18:59+00:00"/>
-\endcode
-*/
-class Node {
- public:
-    // ! ID of the node
-    int64_t id;
-    // ! latitude coordinate
-    double lat;
-    // ! longitude coordinate
-    double lon;
+class Tag;
     /**
-     *    counts the rate, how much this node is used in different ways
-     */
-    unsigned short numsOfUse;
+      @code
+      <node id="122603925" lat="53.0780875" lon="8.1351704"
+      user="artus70" visible="true" timestamp="2007-11-18T22:18:59+00:00"/>
+      </node>
+
+      <node id="27526559" lat="45.5163189" lon="-122.7922059"
+      version="22" timestamp="2012-12-20T03:29:13Z" changeset="14338804" uid="393906" user="Grant Humphries">
+      <tag k="highway" v="traffic_signals"/>
+      </node>
+
+      <tag k="highway" v="traffic_signals"/>
+      <tag k="highway" v="crossing"/>
+      <tag k="exit_to" v="OR 217;Tigard;Salem"/>
+      <tag k="highway" v="motorway_junction"/>
+      <tag k="ref" v="69A"/>
+      <tag k="name" v="Southwest Park & Market"/>
+      <tag k="public_transport" v="stop_position"/>
+      <tag k="railway" v="tram_stop"/>
+      <tag k="ref" v="11011"/>
+      <tag k="tram" v="yes"/>
+      <tag k="highway" v="turning_circle"/>
+
+      @endcode
+      */
+
+class Node : public Element {
  public:
-    /**
-     *    Construktor
-     *     @param id ID of the node
-     *    @param lat latitude
-     *    @param lon longitude
-     */
-    Node(int64_t id = -1, double lat = 0, double lon = 0);
+     Node() = default;
+     Node(const Node&) = default;
+     /**
+      *    @param atts attributes read py the parser
+      */
+     explicit Node(const char **atts);
+     inline std::string geom_str(std::string separator) {
+         return get_attribute("lon") + separator +  get_attribute("lat");
+     }
+
+     inline std::string point_geometry() {
+         return
+             std::string("srid=4326; POINT(")
+             + geom_str(" ") + ")";
+     }
+
+     inline std::string osm_id_str() {
+         return boost::lexical_cast<std::string>(m_osm_id);
+     }
+     double getLength(const Node &previous) const;
+
+
+     inline uint16_t incrementUse() {return ++m_numsOfUse;}
+     inline uint16_t numsOfUse() const {return m_numsOfUse;}
+     inline void numsOfUse(uint16_t val)  {m_numsOfUse = val;}
+
+ private:
+     /**
+      *    counts the rate, how much this node is used in different ways
+      */
+     uint16_t m_numsOfUse;
 };
 
 
diff --git a/src/OSMDocument.cpp b/src/OSMDocument.cpp
index b4441b8..0a62313 100644
--- a/src/OSMDocument.cpp
+++ b/src/OSMDocument.cpp
@@ -1,6 +1,6 @@
 /***************************************************************************
- *   Copyright (C) 2008 by Daniel Wendt                                    *
- *   gentoo.murray at gmail.com                                               *
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -10,141 +10,127 @@
  *   This program is distributed in the hope that it will be useful,       *
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
+ *   GNU General Public License t &or more details.                        *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
  *   Free Software Foundation, Inc.,                                       *
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
-#include <boost/geometry.hpp>
-#include <boost/geometry/geometries/point_xy.hpp>
+
+
+#include <boost/lexical_cast.hpp>
 #include <vector>
 #include <map>
 #include <utility>
 #include <string>
+#include <iostream>
 #include "./OSMDocument.h"
 #include "./Configuration.h"
 #include "./Node.h"
 #include "./Relation.h"
 #include "./Way.h"
-#include "./math_functions.h"
 
 namespace osm2pgr {
 
-OSMDocument::OSMDocument(Configuration &config) : m_rConfig(config) {
+OSMDocument::OSMDocument(const Configuration &config, size_t lines) :
+    m_nodesErrs(0),
+    m_rConfig(config),
+    m_lines(lines) {
 }
 
-OSMDocument::~OSMDocument() {
-    ez_mapdelete(m_Nodes);
-    ez_vectordelete(m_Ways);
-    ez_vectordelete(m_Relations);
-    ez_vectordelete(m_SplittedWays);
-}
-void OSMDocument::AddNode(Node* n) {
-    m_Nodes[n->id] = n;
+
+void OSMDocument::AddNode(Node n) {
+    m_Nodes[n.osm_id()] = n;
 }
 
-void OSMDocument::AddWay(Way* w) {
-    m_Ways.push_back(w);
+void OSMDocument::AddWay(Way w) {
+    m_Ways[w.osm_id()] = w;
 }
 
-void OSMDocument::AddRelation(Relation* r) {
+void OSMDocument::AddRelation(const Relation &r) {
     m_Relations.push_back(r);
 }
 
-Node* OSMDocument::FindNode(long long nodeRefId)
-const {
-    std::map<long long, Node*>::const_iterator  it = m_Nodes.find(nodeRefId);
-    return (it != m_Nodes.end()) ? it->second : 0;
+Node*
+OSMDocument::FindNode(int64_t nodeRefId) {
+    auto it = m_Nodes.find(nodeRefId);
+    return &(it->second);
 }
 
-void OSMDocument::SplitWays() {
-    std::vector<Way*>::const_iterator it(m_Ways.begin());
-    std::vector<Way*>::const_iterator last(m_Ways.end());
-
-    //  splitted ways get a new ID
-    long long id = 0;
-
-    while (it != last) {
-        Way* currentWay = *it++;
-
-        // ITERATE THROUGH THE NODES
-        std::vector<Node*>::const_iterator it_node(currentWay->m_NodeRefs.begin());
-        std::vector<Node*>::const_iterator last_node(currentWay->m_NodeRefs.end());
-
-        Node* backNode = currentWay->m_NodeRefs.back();
-
-        while (it_node != last_node) {
-            Node* node = *it_node++;
-            Node* secondNode = 0;
-            Node* lastNode = 0;
-
-            Way* splitted_way = new Way(++id, currentWay->visible,
-                currentWay->osm_id,
-                currentWay->maxspeed_forward,
-                currentWay->maxspeed_backward);
-            splitted_way->name = currentWay->name;
-            splitted_way->type = currentWay->type;
-            splitted_way->clss = currentWay->clss;
-            splitted_way->oneWayType = currentWay->oneWayType;
-
-            std::map<std::string, std::string>::iterator it_tag(currentWay->m_Tags.begin());
-            std::map<std::string, std::string>::iterator last_tag(currentWay->m_Tags.end());
-//            std::cout << "Number of tags: " << currentWay->m_Tags.size() << std::endl;
-//            std::cout << "First tag: " << currentWay->m_Tags.front()->key << ":" << currentWay->m_Tags.front()->value << std::endl;
+bool
+OSMDocument::has_node(int64_t nodeRefId) const {
+    auto it = m_Nodes.find(nodeRefId);
+    return (it != m_Nodes.end());
+}
 
-            // ITERATE THROUGH THE TAGS
+Way*
+OSMDocument::FindWay(int64_t way_id) {
+    auto it = m_Ways.find(way_id);
+    return &(it->second);
+}
 
-            while (it_tag != last_tag) {
-                std::pair<std::string, std::string> pair = *it_tag++;
+bool
+OSMDocument::has_way(int64_t way_id) const {
+    auto it = m_Ways.find(way_id);
+    return (it != m_Ways.end());
+}
 
-                splitted_way->AddTag(pair.first, pair.second);
-            }
+void
+OSMDocument::add_node(Way &way, const char **atts) {
+    auto **attribut = atts;
+    std::string key = *attribut++;
+    std::string value = *attribut++;
+    auto node_id =  (key == "ref")?  boost::lexical_cast<int64_t>(value): -1;
+    if (!has_node(node_id)) {
+        ++m_nodesErrs;
+    } else {
+        auto node = FindNode(node_id);
+        node->incrementUse();
+        way.add_node(node);
+    }
+}
 
-    // GeometryFromText('LINESTRING('||x1||' '||y1||','||x2||' '||y2||')',4326);
-
-            splitted_way->geom = "LINESTRING("+ boost::lexical_cast<std::string>(node->lon) + " " + boost::lexical_cast<std::string>(node->lat) +",";
-
-            splitted_way->AddNodeRef(node);
-
-            bool found = false;
-
-            if (it_node != last_node) {
-                while (it_node != last_node && !found) {
-                    splitted_way->AddNodeRef(*it_node);
-                    if ((*it_node)->numsOfUse > 1) {
-                        found = true;
-                        secondNode = *it_node;
-                        splitted_way->AddNodeRef(secondNode);
-                        double length = getLength(node, secondNode);
-                        if (length < 0)
-                            length*=-1;
-                        splitted_way->length+=length;
-                        splitted_way->geom+= boost::lexical_cast<std::string>(secondNode->lon) + " " + boost::lexical_cast<std::string>(secondNode->lat) + ")";
-                    } else if (backNode == (*it_node)) {
-                        lastNode =*it_node++;
-                        splitted_way->AddNodeRef(lastNode);
-                        double length = getLength(node, lastNode);
-                        if (length < 0)
-                            length*=-1;
-                        splitted_way->length+=length;
-                        splitted_way->geom+= boost::lexical_cast<std::string>(lastNode->lon) + " " + boost::lexical_cast<std::string>(lastNode->lat) + ")";
-                    } else {
-                        splitted_way->geom+= boost::lexical_cast<std::string>((*it_node)->lon) + " " + boost::lexical_cast<std::string>((*it_node)->lat) + ",";
-                        *it_node++;
-                    }
+void
+OSMDocument::add_config(Way &way, const Tag &tag) const {
+    auto  k = tag.key();
+    auto  v = tag.value();
+    /*
+     * for example
+     *  <tag highway=motorway>    // k = highway  v = motorway
+     *  <tag highway=path>    // k = highway  v = motorway
+     *
+     * And the configuration file has:
+     * <type name="highway" id="1">
+     *     <class name="motorway" id="101" priority="1.0" maxspeed="130" />
+     *     // there is no class name="path"
+     */
+    if (m_rConfig.has_class(tag)) {
+        if ((way.tag_config().key() == "" && way.tag_config().value() == "")
+                || (
+                    m_rConfig.has_class(tag)
+                    && m_rConfig.has_class(way.tag_config())
+                    && m_rConfig.class_priority(tag)
+                    < m_rConfig.class_priority(way.tag_config())
+                   )
+           ) {
+            way.tag_config(tag);
+#if 0
+            if (m_rConfig.has_class(way.tag_config())) {
+                way.add_tag(tag);
+
+                auto newValue = m_rConfig.class_default_maxspeed(way.tag_config());
+                if (way.maxspeed_forward() <= 0) {
+                    way.maxspeed_forward(newValue);
+                }
+                if (way.maxspeed_backward() <= 0) {
+                    way.maxspeed_backward(newValue);
                 }
             }
-
-            if (splitted_way->m_NodeRefs.front() != splitted_way->m_NodeRefs.back()) {
-                m_SplittedWays.push_back(splitted_way);
-            } else {
-                delete splitted_way;
-                splitted_way = 0;
-            }
+#endif
         }
     }
-}  // end SplitWays
+}
+
 
-}  // end namespace osm2pgr
+}  // namespace osm2pgr
diff --git a/src/OSMDocument.h b/src/OSMDocument.h
index 0be2be8..4e38b3f 100644
--- a/src/OSMDocument.h
+++ b/src/OSMDocument.h
@@ -1,6 +1,6 @@
 /***************************************************************************
- *   Copyright (C) 2008 by Daniel Wendt       							   *
- *   gentoo.murray at gmail.com   											   *
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -10,7 +10,7 @@
  *   This program is distributed in the hope that it will be useful,       *
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
+ *   GNU General Public License t &or more details.                        *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
@@ -18,11 +18,13 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
+
 #ifndef SRC_OSMDOCUMENT_H_
 #define SRC_OSMDOCUMENT_H_
 
 #include <map>
 #include <vector>
+#include <string>
 #include "./Configuration.h"
 
 namespace osm2pgr {
@@ -33,39 +35,66 @@ class Way;
 class Relation;
 
 /**
-	An osm-document.
+    An osm-document.
 */
 class OSMDocument {
  public:
-    // ! Map, which saves the parsed nodes
-    std::map<long long, Node*> m_Nodes;
-    //! parsed ways
-    std::vector<Way*> m_Ways;
-    //! splitted ways
-    std::vector<Way*> m_SplittedWays;
-
-    std::vector<Relation*> m_Relations;
+    //! Constructor
+    OSMDocument(const Configuration& config, size_t lines);
 
+    inline size_t lines() const {return m_lines;}
+    inline bool has_class(const Tag &tag) const {
+        return m_rConfig.has_class(tag);
+    }
+    inline double class_priority(const Tag &tag) const {
+        return m_rConfig.class_priority(tag);
+    }
+    inline double class_default_maxspeed(const Tag &tag) const {
+        return m_rConfig.class_default_maxspeed(tag);
+    }
 
-    Configuration& m_rConfig;
+    const std::map<int64_t, Node>& nodes() const {return m_Nodes;}
+    const std::map<int64_t, Way>& ways() const {return m_Ways;}
+    const std::vector<Relation>& relations() const {return m_Relations;}
 
- public:
-    //! Constructor
-    OSMDocument(Configuration& config);
-    //! Destructor
-    virtual ~OSMDocument();
     //! add node to the map
-    void AddNode(Node* n);
+    void AddNode(Node n);
+
     //! add way to the map
-    void AddWay(Way* w);
+    void AddWay(Way w);
+
     //! find node by using an ID
-    Node* FindNode(long long nodeRefId) const;
-    //! split the ways
-    void SplitWays();
-    //  Node* getNode(long long nodeRefId);
-    void AddRelation(Relation* r);
-};
+    bool has_node(int64_t nodeRefId) const;
+    Node* FindNode(int64_t nodeRefId);
 
+    bool has_way(int64_t way_id) const;
+    Way* FindWay(int64_t way_id);
+
+    void AddRelation(const Relation &r);
+
+    void add_node(Way &way, const char **atts);
+    size_t nodesErrs() {return m_nodesErrs;}
+
+    /**
+     * add the configuration tag used for the speeds
+     */
+    void add_config(Way &way, const Tag &tag) const;
+
+ private:
+    // ! parsed nodes
+    std::map<int64_t, Node> m_Nodes;
+    //! parsed ways
+    std::map<int64_t, Way> m_Ways;
+    //! parsed relations
+    std::vector<Relation> m_Relations;
+
+
+    size_t m_nodesErrs;
+ public:
+    const Configuration& m_rConfig;
+ private:
+    size_t m_lines;
+};
 
 }  // end namespace osm2pgr
 #endif  // SRC_OSMDOCUMENT_H_
diff --git a/src/OSMDocumentParserCallback.cpp b/src/OSMDocumentParserCallback.cpp
index bc09df2..1c3621c 100644
--- a/src/OSMDocumentParserCallback.cpp
+++ b/src/OSMDocumentParserCallback.cpp
@@ -1,6 +1,6 @@
 /***************************************************************************
- *   Copyright (C) 2008 by Daniel Wendt       							   *
- *   gentoo.murray at gmail.com   											   *
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -10,27 +10,30 @@
  *   This program is distributed in the hope that it will be useful,       *
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
+ *   GNU General Public License t &or more details.                        *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
  *   Free Software Foundation, Inc.,                                       *
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
+
+
+
+#include "./OSMDocumentParserCallback.h"
+
+#include <math.h>
 #include <string>
+#include <cassert>
 #include <iostream>
 #include <sstream>
-#include "math.h"
-#include "./OSMDocumentParserCallback.h"
 #include "./OSMDocument.h"
+#include "./print_progress.h"
 #include "./Relation.h"
+#include "./osm_tag.h"
 #include "./Way.h"
 #include "./Node.h"
-#include "./utils.h"
 
-// define here, which streetstype you want to parse
-// for applying this filter, compile with "DISTRICT" as flag (g++ -DRESTRICT)
-// #define _FILTER if (m_pActWay->highway == "motorway" || m_pActWay->highway == "primary" || m_pActWay->highway == "secondary")
 
 namespace osm2pgr {
 
@@ -51,225 +54,97 @@ namespace osm2pgr {
   </relation>
  */
 
+void
+OSMDocumentParserCallback::show_progress() {
+    if ((++m_line % (m_rDocument.lines() / 100)) == 0) {
+        print_progress(m_rDocument.lines(), m_line % m_rDocument.lines());
+        std::cout << " Total osm elements parsed: " << m_line;
+    }
+}
+
 
 /**
-    Parser callback for OSMDocument files
-*/
-void OSMDocumentParserCallback::StartElement(const char *name, const char** atts) {
-    // START RELATIONS CODE
-    if (strcmp(name, "member") == 0) {
-        // std::cout << "In member..." << std::endl;
-
-        if (m_pActRelation && atts != NULL) {
-            const char** attribut = (const char**)atts;
-            while (*attribut != NULL) {
-                const char* name = *attribut++;
-                const char* value = *attribut++;
-                if (strcmp(name, "ref") == 0) {
-                    long long wayRefId = atoll(value);
-                    m_pActRelation->AddWayRef(wayRefId);
-                }
-            }
-        }
+  Parser callback for OSMDocument files
+  */
+void
+OSMDocumentParserCallback::StartElement(
+        const char *name,
+        const char** atts) {
+    show_progress();
+    if ((m_section == 1 && (strcmp(name, "way") == 0))
+            || (m_section == 2 && (strcmp(name, "relation") == 0))) {
+        ++m_section;
     }
-    // END RELATIONS CODE
 
 
-    if (strcmp(name, "nd") == 0) {
-        if (m_pActWay && atts != NULL) {
-            const char* name = *atts++;
-            const char* value = *atts++;
-            if (strcmp(name, "ref") == 0) {
-                long long nodeRefId = atoll(value);
-                m_pActWay->AddNodeRef(m_rDocument.FindNode(nodeRefId));
-                Node * node = m_rDocument.FindNode(nodeRefId);
-                if (node != 0) {
-                    ++node->numsOfUse;
-                } else {
-                    std::cout << "Reference nd=" << nodeRefId
-                            << " has no corresponding Node Entry (Maybe Node entry after Reference?)" << std::endl;
-                }
-            }
+    if (m_section == 1) {
+        if (strcmp(name, "node") == 0) {
+            last_node = new Node(atts);
         }
-    } else if (strcmp(name, "node") == 0) {
-        if (atts != NULL) {
-            long long id =-1;
-            double lat =-1;
-            double lon =-1;
-            const char** attribut = (const char**)atts;
-            while (*attribut != NULL) {
-                const char* name = *attribut++;
-                const char* value = *attribut++;
-                if (strcmp(name, "id") == 0) {
-                    id = atoll(value);
-                } else if (strcmp(name, "lat") == 0) {
-                    lat = atof(value);
-                } else if (strcmp(name, "lon") == 0) {
-                    lon = atof(value);
-                }
-            }
-            if (id > 0) m_rDocument.AddNode(new Node(id, lat, lon));
-        }
-    } else if (strcmp(name, "relation") == 0) {   // THIS IS THE RELATION CODE...
-        if (atts != NULL) {
-            long long id =-1;
-            const char** attribut = (const char**)atts;
-            while (*attribut != NULL) {
-                const char* name = *attribut++;
-                const char* value = *attribut++;
-                if (strcmp(name, "id") == 0) {
-                    id = atoll(value);
-                }
-            }
-            if (id > 0) m_pActRelation = new Relation(id);
-            // std::cout<<"Starting relation: "<<id<<std::endl;
+#if 0
+        // TODO(vicky) to be used in V.3 for a hstore column
+        if (strcmp(name, "tag") == 0) {
+            last_node->add_tag(Tag(atts));
         }
-    } else if (strcmp(name, "tag") == 0) {  // END OF THE RELATIONS CODE
-        // <tag k="name" v="Pf�nderweg"/>
-        if (atts != NULL) {
-            std::string k;
-            std::string v;
-            const char** attribut = (const char**)atts;
-            while (*attribut != NULL) {
-                const char* name = *attribut++;
-                const char* value = *attribut++;
-                if (strcmp(name, "k") == 0) {
-                    k = value;
-                } else if (strcmp(name, "v") == 0) {
-                    v = value;
-                }
-            }
-            if (!k.empty()) {
-                //  CHECKING OUT SOME DATA...
-                // std::cout<<"k: "<<k<<", v: "<<v<<std::endl;
-                // std::cout<<"m_pActWay: "<<m_rDocument.m_rConfig.m_Types.count(k)<<std::endl;
-                // std::cout<<"thecount: "<<m_rDocument.m_rConfig.m_Types.count(k)<<std::endl;
-                if (m_pActWay && k.compare("name") == 0) {
-                    m_pActWay->name = v;
-                } else if (m_pActWay && k.compare("oneway") == 0) {  // checks ONEWAY tag
-                    // one way tag
-                    if ((v.compare("yes") == 0) || (v.compare("true") == 0) || (v.compare("1") == 0)) {
-                        m_pActWay->oneWayType = YES;
-                    } else {}
-
-                    // check false conditions: 0, no, false
-                    if ((v.compare("no") == 0) || (v.compare("false") == 0) || (v.compare("0") == 0)) {
-                        m_pActWay->oneWayType = NO;
-                    } else {}
-
-                    // check reversible condition
-                    if (v.compare("reversible") == 0) {
-                        m_pActWay->oneWayType = REVERSIBLE;
-                    } else {}
-
-                    // check revers conditions: -1
-                    if ((v.compare("-1") == 0)) {
-                        m_pActWay->oneWayType = REVERSED;
-                    }
-
-                  // in case roundabout, if there is not additional oneway tag, set default oneway to YES
-                } else if (m_pActWay && k.compare("junction") == 0 && v.compare("roundabout") == 0) {
-                    if (m_pActWay->oneWayType == UNKNOWN) m_pActWay->oneWayType= YES;
-                }
-                // handle 3 cases if the key contains maxspeed
-                else if (m_pActWay && k.find("maxspeed") != std::string::npos) {
-                    // If the value contains mph, strip unit, convert to kph.
-                    if (v.find("mph") != std::string::npos) {
-                        // Assume format is /[0-9]{1,3} ?mph/
-                        v = my_utils::read_number_substring(v);
-                        std::ostringstream ostr;
-                        ostr << floor(atoi(v.c_str()) * 1.60934);
-                        v = ostr.str();
-                    }
-                    // handle maxspeed:forward tag
-                    if (k.compare("maxspeed:forward") == 0) {
-                        int mspeed_fwd = 50;
-
-                        if (my_utils::is_number(v)) {
-                            mspeed_fwd = atoi(v.c_str());
-                        } else {
-                            // TODO: handle non-numeric values, ex.: RO:urban
-                            std::cout << "unknown maxspeed1 value: " << v << std::endl;
-                        }
-                        m_pActWay->maxspeed_forward = mspeed_fwd;
-                    }
-                    // handler maxspeed:backward
-                    else if (k.compare("maxspeed:backward") == 0) {
-                        int mspeed_backwd = 50;
+#endif
+        return;
+    }
 
-                        if (my_utils::is_number(v)) {
-                            mspeed_backwd = atoi(v.c_str());
-                        } else {
-                            // TODO: handle non-numeric values, ex.: RO:urban
-                            std::cout << "unknown maxspeed2 value: " << v << std::endl;
-                        }
-                        m_pActWay->maxspeed_backward = mspeed_backwd;
-                    } else if (k.compare("maxspeed") == 0) {
-                        int mspeed_fwd = 50;
-                        int mspeed_backwd = 50;
+    if (m_section == 2) {
+        if (strcmp(name, "way") == 0) {
+            last_way = new Way(atts);
+        }
+        if (strcmp(name, "tag") == 0) {
+            auto tag = last_way->add_tag(Tag(atts));
+            m_rDocument.add_config(*last_way, tag);
+        }
 
-                        if (my_utils::is_number(v)) {
-                            mspeed_fwd = atoi(v.c_str());
-                            mspeed_backwd = atoi(v.c_str());
-                        } else {
-                            // TODO: handle non-numeric values, ex.: RO:urban
-                            std::cout << "unknown maxspeed3 value: " << v << std::endl;
-                        }
-                        m_pActWay->maxspeed_backward = mspeed_backwd;
-                        m_pActWay->maxspeed_forward = mspeed_fwd;
-                    }
-                }
-                // else if (m_pActWay && k.compare("highway") == 0)
-                else if (m_pActWay && m_rDocument.m_rConfig.m_Types.count(k)) {
-                    m_pActWay->type = k;
-                    m_pActWay->clss = v;
+        if (strcmp(name, "nd") == 0) {
+            m_rDocument.add_node(*last_way, atts);
+        }
+        return;
+    }
 
-                    if (m_rDocument.m_rConfig.m_Types.count(m_pActWay->type) && m_rDocument.m_rConfig.m_Types[m_pActWay->type]->m_Classes.count(m_pActWay->clss)) {
-                        m_pActWay->AddTag(k, v);
+    if (m_section == 3) {
+        /*
+         *  START RELATIONS CODE
+         */
+        if (strcmp(name, "relation") == 0) {
+            last_relation = new Relation(atts);
+            return;
+        }
 
-                        // std::cout<<"Added tag: "<<k<<" "<<v<<std::endl;
+        if (strcmp(name, "member") == 0) {
+            /*
+               <member type="node" ref="721818679" role="label"/>
+               <member type="way" ref="173424370" role=""/>
+               <member type="way" ref="48435091" role="link"/>
+               */
+            auto way_id = last_relation->add_member(atts);
+            if (way_id == -1) return;
+            assert(!last_relation->way_refs().empty());
+            if (m_rDocument.has_way(way_id)) {
+                Way* way_ptr = m_rDocument.FindWay(way_id);
+                way_ptr->insert_tags(last_relation->tags());
+            } else {
+                assert(!last_relation->way_refs().empty());
+                last_relation->way_refs().pop_back();
+            }
 
-                        // set default maxspeed values from classes, if not set previously (default: -1)
-                        if (m_pActWay->maxspeed_forward <= 0) {
-                            int newValue = m_rDocument.m_rConfig.m_Types[m_pActWay->type]->m_Classes[m_pActWay->clss]->default_maxspeed;
-                            m_pActWay->maxspeed_forward = newValue;
-                        }
-                        if (m_pActWay->maxspeed_backward <= 0) {
-                            int newValue = m_rDocument.m_rConfig.m_Types[m_pActWay->type]->m_Classes[m_pActWay->clss]->default_maxspeed;
-                            m_pActWay->maxspeed_backward = newValue;
-                        }
-                    }
-                }
-                // START TAG FOR RELATION
-                else if (m_pActRelation && m_rDocument.m_rConfig.m_Types.count(k))  {
-                    if (m_rDocument.m_rConfig.m_Types.count(k) && m_rDocument.m_rConfig.m_Types[k]->m_Classes.count(v)) {
-                        m_pActRelation->AddTag(k, v);
-                        // std::cout<<"Added Relation tag: "<<k<<" "<<v<<std::endl;
+            return;
+        }
+        if (strcmp(name, "tag") == 0) {
+            if (atts != NULL) {
+                auto tag = last_relation->add_tag(Tag(atts));
+                if (!tag.key().empty()) {
+                    if ((last_relation->tag_config().key() == "" && last_relation->tag_config().value() == "")
+                            || (m_rDocument.has_class(tag)
+                                && m_rDocument.has_class(last_relation->tag_config())
+                                && (m_rDocument.class_priority(tag)
+                                    < m_rDocument.class_priority(last_relation->tag_config())))) {
+                        last_relation->tag_config(tag);
                     }
-                    // std::cout<<"Relations tag: "<<k<<" "<<v<<std::endl;
                 }
-                if (m_pActRelation && k.compare("name") == 0) {
-                    m_pActRelation->name = v;
-                }
-                // END TAG FOR RELATION
-            }
-        }
-    } else if (strcmp(name, "way") == 0) {
-        if (atts != NULL) {
-            long long id =-1;
-            bool visibility = false;
-            const char** attribut = (const char**)atts;
-            while (*attribut != NULL) {
-                const char* name = *attribut++;
-                const char* value = *attribut++;
-                if (strcmp(name, "id") == 0) {
-                    id = atoll(value);
-                } else if (strcmp(name, "visible") == 0) {
-                    visibility = strcmp(value, "true") == 0;
-                }
-            }
-            if (id > 0) {
-                m_pActWay = new Way(id, visibility, id , -1, -1);
             }
         }
     } else if (strcmp(name, "osm") == 0) {
@@ -277,37 +152,53 @@ void OSMDocumentParserCallback::StartElement(const char *name, const char** atts
 }
 
 void OSMDocumentParserCallback::EndElement(const char* name) {
+    if (strcmp(name, "node") == 0) {
+        m_rDocument.AddNode(*last_node);
+        delete last_node;
+        return;
+    }
     if (strcmp(name, "way") == 0) {
-        //  #ifdef RESTRICT
-        // _FILTER
-
-        if (m_rDocument.m_rConfig.m_Types.count(m_pActWay->type) && m_rDocument.m_rConfig.m_Types[m_pActWay->type]->m_Classes.count(m_pActWay->clss)) {
-        // #endif
-
-        // Comment out the following to get more log output
-        // std::cout<<"We need a way of type "<<m_pActWay->type<<" and class "<< m_pActWay->clss<<std::endl;
+        if (m_rDocument.has_class(last_way->tag_config())) {
+            auto newValue = m_rDocument.class_default_maxspeed(
+                    last_way->tag_config());
 
-            m_rDocument.AddWay(m_pActWay);
-            // std::cout << "First tag: " << m_pActWay->m_Tags.back()->key << ":" << m_pActWay->m_Tags.back()->value << std::endl;
-
-
-        // #ifdef RESTRICT
-        } else {
-        // std::cout<<"We DON'T need a way of type "<<m_pActWay->type<<" and class "<< m_pActWay->clss<<std::endl;
-            // delete m_pActWay;
+            if (last_way->maxspeed_forward() <= 0) {
+                last_way->maxspeed_forward(newValue);
+            }
+            if (last_way->maxspeed_backward() <= 0) {
+                last_way->maxspeed_backward(newValue);
+            }
         }
-        // #endif
 
-        m_pActWay = 0;
-    }
-    // THIS IS THE RELATION CODE...
-    else if (strcmp(name, "relation") == 0) {
-        m_rDocument.AddRelation(m_pActRelation);
-        m_pActRelation = 0;
+        m_rDocument.AddWay(*last_way);
+        delete last_way;
+        return;
+
+    } else if (strcmp(name, "relation") == 0) {
+        if (m_rDocument.has_class(last_relation->tag_config())) {
+            for (auto it = last_relation->way_refs().begin();  it != last_relation->way_refs().end(); ++it) {
+                auto way_id = *it;
+                assert(m_rDocument.has_way(way_id));
+                if (m_rDocument.has_way(way_id)) {
+                    Way* way_ptr = m_rDocument.FindWay(way_id);
+                    way_ptr->tag_config(last_relation->tag_config());
+                    auto newValue = m_rDocument.class_default_maxspeed(
+                            last_relation->tag_config());
+                    if (way_ptr->maxspeed_forward() <= 0) {
+                        way_ptr->maxspeed_forward(newValue);
+                    }
+                    if (way_ptr->maxspeed_backward() <= 0) {
+                        way_ptr->maxspeed_backward(newValue);
+                    }
+                }
+            }
+            m_rDocument.AddRelation(*last_relation);
+        }
+        delete last_relation;
 
-        // std::cout<<"Adding relation: "<<m_pActRelation->id<<std::endl;
+    } else if (strcmp(name, "osm") == 0) {
+        show_progress();
     }
-    // END OF THE RELATIONS CODE
 }
 
 }  // end namespace osm2pgr
diff --git a/src/OSMDocumentParserCallback.h b/src/OSMDocumentParserCallback.h
index ec8950b..5b434ac 100644
--- a/src/OSMDocumentParserCallback.h
+++ b/src/OSMDocumentParserCallback.h
@@ -1,6 +1,6 @@
 /***************************************************************************
- *   Copyright (C) 2008 by Daniel Wendt                                    *
- *   gentoo.murray at gmail.com                                               *
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -10,7 +10,7 @@
  *   This program is distributed in the hope that it will be useful,       *
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
+ *   GNU General Public License t &or more details.                        *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
@@ -18,8 +18,17 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
+
 #ifndef SRC_OSMDOCUMENTPARSERCALLBACK_H_
 #define SRC_OSMDOCUMENTPARSERCALLBACK_H_
+#pragma once
+
+#if __GNUC__ > 4 || \
+            (__GNUC__ == 4 && (__GNUC_MINOR__ >= 6))
+#else
+#define nullptr NULL
+#endif
+
 
 #include <string.h>
 #include "./XMLParser.h"
@@ -27,6 +36,7 @@
 namespace osm2pgr {
 
 class OSMDocument;
+class Node;
 class Way;
 class Relation;
 
@@ -38,32 +48,36 @@ class OSMDocumentParserCallback :
     //! reference to a OSMDocument object
     OSMDocument& m_rDocument;
     //! current way, which will be parsed
-    Way* m_pActWay;
+    // Way* m_pActWay;
     Relation* m_pActRelation;
 
     virtual void StartElement(const char *name, const char** atts);
 
     virtual void EndElement(const char* name);
 
-#if 0
-    virtual void SetContent(const char* ch, int len)=0;
-
-    virtual void ProcessingInstruction(const char* target, const char* data)=0;
-
-    virtual void CDataBlockInternal(const char *value, int len)=0;
-#endif
  public:
     /**
      *    Constructor
      */
-    OSMDocumentParserCallback(OSMDocument& doc)
+    explicit OSMDocumentParserCallback(OSMDocument& doc)
     :
         m_rDocument(doc),
-        m_pActWay(0),
-        m_pActRelation(0)
-
-    {
+        m_pActRelation(0),
+        last_node(nullptr),
+        last_way(nullptr),
+        last_relation(nullptr),
+        m_line(0),
+        m_section(1) {
     }
+ private:
+    void show_progress();
+
+ private:
+    Node *last_node;
+    Way *last_way;
+    Relation* last_relation;
+    size_t m_line;
+    int m_section;
 };  // class OSMDocumentParserCallback
 
 }  // end namespace osm2pgr
diff --git a/src/Relation.cpp b/src/Relation.cpp
index c46a0a1..0d2fcd3 100644
--- a/src/Relation.cpp
+++ b/src/Relation.cpp
@@ -1,6 +1,6 @@
 /***************************************************************************
- *   Copyright (C) 2008 by Daniel Wendt   								   *
- *   gentoo.murray at gmail.com   											   *
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -10,35 +10,53 @@
  *   This program is distributed in the hope that it will be useful,       *
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
+ *   GNU General Public License t &or more details.                        *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
  *   Free Software Foundation, Inc.,                                       *
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
+
+
+#include <boost/lexical_cast.hpp>
 #include <string>
 #include "./Relation.h"
-//#include "./Way.h"
-
 
 namespace osm2pgr {
 
-Relation::Relation(int64_t id)
-:
-    id(id) {
-}
 
-Relation::~Relation() {
+Relation::Relation(const char **atts) :
+    Element(atts) { }
+
+
+
+int64_t
+Relation::add_member(const char **atts) {
+    auto **attribut = atts;
+    std::string type;
+    int64_t osm_id(0);
+    std::string role;
+    while (*attribut != NULL) {
+        std::string key = *attribut++;
+        std::string value = *attribut++;
+        /*
+         * currently only adding way
+         */
+        if (key == "type") {
+            if (value != "way") return -1;
+        }
+        if (key == "ref") {
+            osm_id = boost::lexical_cast<int64_t>(value);
+        }
+        if (key == "role") {
+            role = value;
+        }
+    }
+    m_WayRefs.push_back(osm_id);
+    return osm_id;
 }
 
-void Relation::AddWayRef(int64_t pID) {
-    if (pID) m_WayRefs.push_back(pID);
-}
-
-void Relation::AddTag(std::string key, std::string value) {
-    m_Tags[key] = value;
-}
 
 }  // end namespace osm2pgr
 
diff --git a/src/Relation.h b/src/Relation.h
index ecfb77e..7e50286 100644
--- a/src/Relation.h
+++ b/src/Relation.h
@@ -1,6 +1,6 @@
 /***************************************************************************
- *   Copyright (C) 2008 by Daniel Wendt                                    *
- *   gentoo.murray at gmail.com                                               *
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -10,64 +10,66 @@
  *   This program is distributed in the hope that it will be useful,       *
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
+ *   GNU General Public License t &or more details.                        *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
  *   Free Software Foundation, Inc.,                                       *
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
+
 #ifndef SRC_RELATION_H_
 #define SRC_RELATION_H_
 
 #include <vector>
 #include <map>
 #include <string>
+#include "./osm_element.h"
 
 namespace osm2pgr {
 class Way;
 
 /**
 \code
- <way id="20215432" visible="true" timestamp="2008-01-09T22:35:16+00:00" user="Pferdo">
-    <nd ref="213794929"/>
-    <nd ref="213795470"/>
-    <nd ref="213795483"/>
-    <nd ref="213795493"/>
-    <nd ref="213795506"/>
-    <nd ref="213795517"/>
-    <nd ref="213795527"/>
-    <nd ref="213795541"/>
-    <nd ref="213795552"/>
-    <nd ref="213795561"/>
-    <nd ref="213795571"/>
-    <tag k="name" v="Pf�nderweg"/>
-    <tag k="created_by" v="JOSM"/>
-    <tag k="highway" v="residential"/>
-  </way>
+
+<relation id="2781938" version="1" timestamp="2013-02-24T05:24:08Z" changeset="15143772" uid="621319" user="hayashi">
+<member type="way" ref="206946707" role="outer"/>
+<member type="way" ref="206946714" role="inner"/>
+<tag k="building" v="yes"/>
+<tag k="type" v="multipolygon"/>
+</relation>
+
+<relation id="6127135" version="2" timestamp="2016-04-11T03:26:53Z" changeset="38464643" uid="624003" user="eugenebata">
+<member type="way" ref="184275824" role="link"/>
+<member type="way" ref="374341622" role=""/>
+<tag k="name" v="阪神高速31号神戸山手線"/>
+<tag k="name:en" v="Hanshin Expressway Route 31"/>
+<tag k="ref" v="31"/>
+<tag k="route" v="road"/>
+<tag k="type" v="route"/>
+</relation>
+
 \endcode
 */
-class Relation {
+class Relation : public Element{
  public:
-    long long id;
-    std::string name;
-    std::vector<int64_t> m_WayRefs;
-    std::map<std::string, std::string> m_Tags;
+     /** 
+      *    @param atts attributes read py the parser
+      */
+     explicit Relation(const char ** atts);
+     Relation() = delete;
+     Relation(const Relation&) = default;
+     std::vector<int64_t> way_refs() const {return m_WayRefs;}
+     std::vector<int64_t>& way_refs() {return m_WayRefs;}
 
- public:
-    /** 
-     *    Constructor
-     *    @param id ID of the way
-     */
-    Relation(int64_t id);
-    //! Destructor
-    ~Relation();
-    /**
-     *    saves the nodes of the way  
-     *    @param pNode node
-     */
-    void AddWayRef(int64_t pID);
-    void AddTag(std::string key, std::string value);
+     /**
+      *    saves the nodes of the way  
+      *    @param atts member attributes read py the parser
+      */
+     int64_t add_member(const char **atts);
+
+ private:
+     std::vector<int64_t> m_WayRefs;
 };
 
 
diff --git a/src/Type.cpp b/src/Type.cpp
index dda62ec..3786144 100644
--- a/src/Type.cpp
+++ b/src/Type.cpp
@@ -1,39 +1,56 @@
 /***************************************************************************
-*   Copyright (C) 2008 by Daniel Wendt                                    *
-*   gentoo.murray at gmail.com                                               *
-*                                                                         *
-*   This program is free software; you can redistribute it and/or modify  *
-*   it under the terms of the GNU General Public License as published by  *
-*   the Free Software Foundation; either version 2 of the License, or     *
-*   (at your option) any later version.                                   *
-*                                                                         *
-*   This program is distributed in the hope that it will be useful,       *
-*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
-*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
-*   GNU General Public License for more details.                          *
-*                                                                         *
-*   You should have received a copy of the GNU General Public License     *
-*   along with this program; if not, write to the                         *
-*   Free Software Foundation, Inc.,                                       *
-*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
-***************************************************************************/
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License t &or more details.                        *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#include <boost/lexical_cast.hpp>
 #include <string>
-// #include "./stdafx.h"
+#include <map>
+#include "./Class.h"
 #include "./Type.h"
 
 namespace osm2pgr {
 
-Type::Type(long long id, std::string name)
-:
-  id(id),
-  name(name) {
+void Type::AddClass(const Class &pClass) {
+    m_Classes[pClass.name()] = pClass;
 }
 
-Type::~Type() {
+
+Type::Type(const char **atts) {
+    auto **attribut = atts;
+    while (*attribut != NULL) {
+        std::string name = *attribut++;
+        std::string value = *attribut++;
+        if (name == "id") {
+            m_id = boost::lexical_cast<int64_t>(value);
+        } else if (name == "name") {
+            m_name = value;
+        } else {
+            auto tag_key = boost::lexical_cast<std::string>(name);
+            auto tag_value = boost::lexical_cast<std::string>(value);
+            m_tags[tag_key] = tag_value;
+        }
+    }
 }
 
-void Type::AddClass(Class* pClass ) {
-  if (pClass) m_Classes[pClass->name] = pClass;
+void
+Type::add_class(const char **atts) {
+    AddClass(Class(atts));
 }
 
 
diff --git a/src/Type.h b/src/Type.h
index f6fb6a0..174f101 100644
--- a/src/Type.h
+++ b/src/Type.h
@@ -1,27 +1,29 @@
 /***************************************************************************
-*   Copyright (C) 2008 by Daniel Wendt                                    *
-*   gentoo.murray at gmail.com                                               *
-*                                                                         *
-*   This program is free software; you can redistribute it and/or modify  *
-*   it under the terms of the GNU General Public License as published by  *
-*   the Free Software Foundation; either version 2 of the License, or     *
-*   (at your option) any later version.                                   *
-*                                                                         *
-*   This program is distributed in the hope that it will be useful,       *
-*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
-*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
-*   GNU General Public License for more details.                          *
-*                                                                         *
-*   You should have received a copy of the GNU General Public License     *
-*   along with this program; if not, write to the                         *
-*   Free Software Foundation, Inc.,                                       *
-*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
-***************************************************************************/
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License t &or more details.                        *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
 
 #ifndef SRC_TYPE_H_
 #define SRC_TYPE_H_
 
 #include <map>
+#include <cstdint>
 #include <string>
 #include "./Class.h"
 
@@ -29,25 +31,39 @@ namespace osm2pgr {
 
 class Type {
  public:
-    //  std::vector<Class*> m_ClassRefs;
-    std::map<std::string, Class*> m_Classes;
-    //  std::map<long long, Class*> m_Classes;
-    long long id;
-    std::string name;
- public:
-    /** 
-     *    Constructor
-     *    @param name name of the type
+    Type() = default;
+    Type(const Type &) = default;
+    /**
+     *    @param atts attributes read py the parser
      */
-    Type(long long id, std::string);
-    //! Destructor
-    ~Type();
+    explicit Type(const char **atts);
+    inline int64_t id() const {return m_id;}
+    inline std::string name() const {return m_name;}
+    void add_class(const char **atts);
+    std::map<std::string, Class> classes() const {
+        return m_Classes;
+    }
+    std::map<std::string, Class>& classes() {
+        return m_Classes;
+    }
+
+    inline bool has_class(const std::string &class_name) const {
+        return m_Classes.count(class_name);
+    }
+
+ private:
     /**
      *    saves the classes of the type
      *    @param pClass class
      */
-    void AddClass(Class* pClass);
+    void AddClass(const Class &pClass);
+
+ private:
+    std::map<std::string, Class> m_Classes;
+    int64_t m_id;
+    std::string m_name;
+    std::map<std::string, std::string> m_tags;
 };
 
-}  // end namespace osm2pgr
-#endif
+}  // namespace osm2pgr
+#endif  // SRC_TYPE_H_
diff --git a/src/Way.cpp b/src/Way.cpp
index 9a908af..a4ffa4e 100644
--- a/src/Way.cpp
+++ b/src/Way.cpp
@@ -1,6 +1,6 @@
 /***************************************************************************
- *   Copyright (C) 2008 by Daniel Wendt   								   *
- *   gentoo.murray at gmail.com   											   *
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -10,7 +10,7 @@
  *   This program is distributed in the hope that it will be useful,       *
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
+ *   GNU General Public License t &or more details.                        *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
@@ -18,45 +18,333 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
-#include <string>
+
 #include "Way.h"
+#include "boost/lexical_cast.hpp"
+#include <algorithm>
+#include <string>
+#include <cassert>
+#include <map>
+#include <vector>
+#include <iostream>
+#include "./OSMDocument.h"
+#include "./osm_tag.h"
+#include "./Node.h"
+
 
 
 namespace osm2pgr {
 
-Way::Way(int64_t id, bool visible, int64_t osm_id, int maxspeed_forward, int maxspeed_backward)
-:
-	id(id),
-	visible(visible),
-	length(0),
-	maxspeed_forward(maxspeed_forward),
-	maxspeed_backward(maxspeed_backward),
-	oneWayType(UNKNOWN),
-	osm_id(osm_id) {
+
+Way::Way(const char **atts) :
+    Element(atts),
+    m_maxspeed_forward(-1),
+    m_maxspeed_backward(-1),
+    m_oneWay("UNKNOWN") { }
+
+
+
+Tag
+Way::add_tag(const Tag &tag) {
+    m_tags[tag.key()] = tag.value();
+    oneWay(tag);
+    max_speed(tag);
+    return tag;
+}
+
+
+void
+Way::add_node(Node *node) {
+    assert(node);
+    m_NodeRefs.push_back(node);
+}
+
+
+
+std::string
+Way::geometry_str() const {
+    return geometry_str(m_NodeRefs);
+}
+
+std::string
+Way::length_str() const {
+    return length_str(m_NodeRefs);
+}
+
+
+std::string
+Way::geometry_str(const std::vector<Node*> &nodeRefs) const {
+    std::string geometry("LINESTRING(");
+
+    for (auto it = nodeRefs.begin();
+            it != nodeRefs.end();
+            ++it) {
+        auto node_ptr = *it;
+
+        geometry += node_ptr->geom_str(" ");
+        geometry += ", ";
+    }
+    geometry[geometry.size() - 2] = ')';
+    return geometry;
+}
+
+
+std::string
+Way::length_str(const std::vector<Node*> &nodeRefs) const {
+    double length = 0;
+    auto prev_node_ptr = nodeRefs.front();
+
+    for (auto it = nodeRefs.begin();
+            it != nodeRefs.end();
+            ++it) {
+        auto node_ptr = *it;
+
+        length  += node_ptr->getLength(*prev_node_ptr);
+        prev_node_ptr = node_ptr;
+    }
+
+    return boost::lexical_cast<std::string>(length);
+}
+
+
+
+std::vector<std::vector<Node*>>
+Way::split_me() {
+    if (nodeRefs().size() < 2) {
+        /*
+         * The way is ill formed
+         */
+        return std::vector<std::vector<Node*>>();
+    }
+
+    std::vector<std::vector<Node*>> m_split_ways;
+    auto it_node(nodeRefs().begin());
+    auto last_node(nodeRefs().end());
+
+    while (it_node != last_node) {
+        /*
+         * starting a new split
+         */
+        std::vector<Node*> split_way;
+        split_way.push_back(*it_node);
+
+        ++it_node;
+
+        if (it_node != last_node) {
+            while (it_node != last_node) {
+                split_way.push_back(*it_node);
+
+                if ((*it_node)->numsOfUse() > 1) {
+                    break;
+                }
+                ++it_node;
+            }
+        }
+
+        if (split_way.size() > 1) m_split_ways.push_back(split_way);
+    }
+    return m_split_ways;
+}
+
+
+
+std::string
+Way::oneWay() const {
+    return m_oneWay;
+}
+
+void
+Way::oneWay(const Tag &tag) {
+    auto key = tag.key();
+    auto value = tag.value();
+    if (key != "oneway") {
+        implied_oneWay(tag);
+        return;
+    }
+
+    // one way tag
+    if ((value == "yes") || value == "true" || value == "1") {
+        m_oneWay = "YES";
+    }
+
+    // check false conditions: 0, no, false
+    if ((value == "no") || value == "false" || value == "1") {
+        m_oneWay = "NO";
+    }
+
+    // check reversible condition
+    if (value == "reversible") {
+        m_oneWay = "REVERSIBLE";
+    }
+
+    // check revers conditions: -1
+    if (value == "-1") {
+        m_oneWay = "REVERSED";
+    }
+}
+
+void
+Way::implied_oneWay(const Tag &tag) {
+    auto key = tag.key();
+    auto value = tag.value();
+    /*
+     * was tagged, so not using implied tagging
+     */
+    if (m_oneWay != "UNKNOWN") return;
+
+    if ((key == "junction" && value == "roundabout")
+            || (key == "highway"
+                && (value == "motorway"
+                    || value == "trunk") )) {
+        m_oneWay == "YES";
+        return;
+    }
+
+    if (key == "highway"
+            && (value == "primary"
+                || value == "secondary"
+                || value == "tertiary")) {
+        m_oneWay == "NO";
+        return;
+    }
 }
 
 #if 0
-Way::~Way()
-{
+void
+Way::pedestrian(const std::string &key, const std::string &value) {
+    // TODO(vicky) for 3.0
+    // m_pedestrian("UNKNOWN") <-- the default in the constructor
+    if ((key == "sidewak" && value == "no")
+            || (key == "foot" && value == "no")) {
+        m_pedestrian = "NO";
+    }
+
+    if ((key == "highway" && value == "pedestrian") {
+            || (key == "highway" && value == "footway")
+            || (key == "highway" && value == "cycleway")
+            || (key == "highway" && value == "bridleway")
+            || (key == "highway" && value == "track")
+            || (key == "sidewak" && value != "no")  )
+        || (key == "foot" && value != "no")  )
+            || (key == "highway" && value == "steps") {
+                m_pedestrian = "YES";
+                return
+            }
+    }
 }
 #endif
 
-void Way::AddNodeRef( Node* pNode )
-{
-	if( pNode ) m_NodeRefs.push_back(pNode);
+bool
+Way::is_number(const std::string& s) const {
+    std::string::const_iterator it = s.begin();
+    while (it != s.end() && std::isdigit(*it)) ++it;
+    return !s.empty() && it == s.end();
 }
 
-void Way::AddTag( std::string key , std::string value)
-{
-	m_Tags[key] = value;
+
+/*
+ * takes the fist value found
+ */
+double
+Way::get_kph(const std::string &value) const {
+    auto mph_pos = value.find(" mph");
+    if (mph_pos != std::string::npos) {
+        auto newstr = value;
+        newstr.erase(mph_pos, std::string::npos);
+        if (is_number(newstr)) {
+            return boost::lexical_cast<double>(newstr) * 1.609346;
+        }
+    }
+
+    mph_pos = value.find(" knots");
+    if (mph_pos != std::string::npos) {
+        auto newstr = value;
+        newstr.erase(mph_pos, std::string::npos);
+        if (is_number(newstr)) {
+            return boost::lexical_cast<double>(newstr) * 1.852;
+        }
+    }
+    if (is_number(value)) {
+        return boost::lexical_cast<double>(value);
+    }
+    // TODO(vicky): handle non-numeric values, ex.: RO:urban
+    // maybe using a configuration option
+    // http://wiki.openstreetmap.org/wiki/Speed_limits
+    //
+    // TODO(vicky): handle multiple values for lanes
+    // the way with N lanes generates N ways that have to be split
+    // with the different Speeds ???
+    return 50;
 }
 
-bool Way::HasTag(std::string key)
-{
-	return (m_Tags.count(key)>0);
+
+
+
+void
+Way::max_speed(const Tag &tag) {
+    auto key = tag.key();
+    auto value = tag.value();
+    if (key == "maxspeed:forward" && m_maxspeed_forward <=0) {
+        m_maxspeed_forward = get_kph(value);
+        return;
+    }
+    if (key == "maxspeed:backward" && m_maxspeed_backward <=0) {
+        m_maxspeed_backward = get_kph(value);
+        return;
+    }
+    if (key == "maxspeed") {
+        if (m_maxspeed_forward <=0) { 
+            m_maxspeed_forward = get_kph(value);
+        }
+        if (m_maxspeed_backward <=0) {
+            m_maxspeed_backward = get_kph(value);
+        }
+        return;
+    }
 }
 
 
+std::string
+Way::oneWayType_str() const {
+    if (m_oneWay == "YES") return "1";
+    if (m_oneWay == "NO") return  "2";
+    if (m_oneWay == "REVERSIBLE") return  "3";
+    if (m_oneWay == "REVERSED") return "-1";
+    if (m_oneWay == "UNKNOWN") return "0";
+    return "0";
+}
+
+void
+Way::insert_tags(const std::map<std::string, std::string> &tags) {
+    for (auto it = tags.begin(); it != tags.end(); ++it) {
+        auto tag = *it;
+        m_tags[tag.first] = tag.second;
+    }
+}
+
+
+
+#ifndef NDEBUG
+std::ostream& operator<<(std::ostream &os, const Way &way) {
+    std::cout << "\nWay"
+        << "\t m_osm_id: " << way.m_osm_id
+        << "\t m_tag_config: " << way.m_tag_config
+        << "\t m_visible: " << way.m_visible
+        << "\t m_maxspeed_forward: " << way.m_maxspeed_forward
+        << "\t m_maxspeed_backward: " << way.m_maxspeed_backward
+        << "\t m_oneWay: " << way.m_oneWay;
+    std::cout << "\n\n ************ attributes: " << way.attributes_str();
+    std::cout << "\n\n ************ tags: " << way.tags_str();
+    std::cout << "\n nodes: \n";
+    for (auto it = way.m_NodeRefs.begin(); it != way.m_NodeRefs.end(); ++it) {
+        auto e = *it;
+        std::cout << e->osm_id() << ", ";
+    }
+
+    return os;
+}
+#endif
+
 
-} // end namespace osm2pgr
+}  // namespace osm2pgr
 
diff --git a/src/Way.h b/src/Way.h
index 34bb3fb..3ce8362 100644
--- a/src/Way.h
+++ b/src/Way.h
@@ -1,6 +1,6 @@
 /***************************************************************************
- *   Copyright (C) 2008 by Daniel Wendt   								   *
- *   gentoo.murray at gmail.com   											   *
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -10,93 +10,124 @@
  *   This program is distributed in the hope that it will be useful,       *
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
+ *   GNU General Public License t &or more details.                        *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
  *   Free Software Foundation, Inc.,                                       *
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
-#ifndef WAY_H
-#define WAY_H
 
+#ifndef SRC_WAY_H_
+#define SRC_WAY_H_
+
+#include <boost/lexical_cast.hpp>
 #include <vector>
 #include <map>
+#include <string>
+#include "./osm_element.h"
+#include "./Node.h"
+
 namespace osm2pgr {
-	class Node;
 
-	enum OneWayType{ UNKNOWN = 0, YES = 1, NO = 2, REVERSED = -1, REVERSIBLE = 3};
 
 /**
-\code
- <way id="20215432" visible="true" timestamp="2008-01-09T22:35:16+00:00" user="Pferdo">
-    <nd ref="213794929"/>
-    <nd ref="213795470"/>
-    <nd ref="213795483"/>
-    <nd ref="213795493"/>
-    <nd ref="213795506"/>
-    <nd ref="213795517"/>
-    <nd ref="213795527"/>
-    <nd ref="213795541"/>
-    <nd ref="213795552"/>
-    <nd ref="213795561"/>
-    <nd ref="213795571"/>
-    <tag k="name" v="Pf�nderweg"/>
-    <tag k="created_by" v="JOSM"/>
-    <tag k="highway" v="residential"/>
+  \code
+  <way id="20215432" visible="true" timestamp="2008-01-09T22:35:16+00:00" user="Pferdo">
+  <nd ref="213794929"/>
+  <nd ref="213795470"/>
+  <nd ref="213795483"/>
+  <nd ref="213795493"/>
+  <nd ref="213795506"/>
+  <nd ref="213795517"/>
+  <nd ref="213795527"/>
+  <nd ref="213795541"/>
+  <nd ref="213795552"/>
+  <nd ref="213795561"/>
+  <nd ref="213795571"/>
+  <tag k="name" v="Pfnderweg"/>
+  <tag k="created_by" v="JOSM"/>
+  <tag k="highway" v="residential"/>
   </way>
-\endcode
-*/
-class Way
-{
-public:
-	//! Do not delete nodes in this container!
-	std::vector<Node*> m_NodeRefs;
-	std::map<std::string, std::string> m_Tags;
-	//! ID of the way
-	int64_t id;
-	bool visible;
-	//! name of the street
-	std::string name;
-	//! type of the street, for example "motorway"
-	//std::string highway;
-	
-	std::string type;
-	std::string clss;
-
-	//int64_t type;
-	//int64_t clss;
-	
-	//! geometry of the street
-	std::string geom;
-	//! length of the street
-	double length;
-
-	int maxspeed_forward;
-	int maxspeed_backward;
-
-	OneWayType oneWayType;
-	
-	int64_t osm_id;
-
-
-public:
-	/** 
-	 *	Constructor
-	 *	@param id ID of the way
-	 */
-	Way(int64_t id, bool visible, int64_t osm_id,  int maxspeed_forward, int maxspeed_backward);
-	//! Destructor
-	// ~Way();
-	/**
-	 *	saves the nodes of the way  
-	 *	@param pNode node
-	 */
-	void AddNodeRef( Node* pNode );
-	void AddTag( std::string key, std::string value);
-	bool HasTag(std::string key);
-};
+  \endcode
+  */
+class Way : public Element {
+ public:
+     Way() = default;
+
+     /**
+      *  @param atts attributes read py the parser
+      */
+     explicit Way(const char **atts);
+     Tag add_tag(const Tag &tag);
+     void add_node(Node* node);
+
+     std::vector<Node*>& nodeRefs() {return m_NodeRefs;}
+     const std::vector<Node*> nodeRefs() const {return m_NodeRefs;}
+
+
+ public:
+     inline void maxspeed_forward(double p_max) {m_maxspeed_forward = p_max;}
+     inline void maxspeed_backward(double p_max) {m_maxspeed_backward = p_max;}
+
+     inline std::string name() const {return has_tag("name")? get_tag("name") : "";}
+
+
+     std::string oneWay() const;
+     std::string oneWayType_str() const;
+     inline bool is_oneway() const { return m_oneWay == "YES";}
+     inline bool is_reversed() const { return m_oneWay == "REVERSED";}
+
+     inline double maxspeed_forward() const {return m_maxspeed_forward;}
+     inline double maxspeed_backward() const { return m_maxspeed_backward;}
+
+     std::string geometry_str() const;
+     std::string length_str() const;
+
 
+     inline std::string maxspeed_forward_str() const {
+         return boost::lexical_cast<std::string>(
+                 static_cast<int>(m_maxspeed_forward));
+     }
+     inline std::string maxspeed_backward_str() const {
+         return boost::lexical_cast<std::string>(
+                 static_cast<int>(m_maxspeed_backward));
+     }
 
-} // end namespace osm2pgr
+
+     //! splits the way
+     std::vector<std::vector<Node*>> split_me();
+     std::string geometry_str(const std::vector<Node*> &) const;
+     std::string length_str(const std::vector<Node*> &) const;
+
+     /**
+      * to insert the relations tags
+      */
+     void insert_tags(const std::map<std::string, std::string> &tags);
+
+#ifndef NDEBUG
+     friend
+     std::ostream& operator<<(std::ostream &, const Way &);
 #endif
+
+
+ private:
+     bool is_number(const std::string& s) const;
+     double get_kph(const std::string &value) const;
+     void max_speed(const Tag& tag);
+     void oneWay(const Tag& tag);
+     void implied_oneWay(const Tag& tag);
+
+
+ private:
+     std::vector<Node*> m_NodeRefs;
+
+     double m_maxspeed_forward;
+     double m_maxspeed_backward;
+
+     std::string m_oneWay;
+};
+
+
+}  // end namespace osm2pgr
+#endif  // SRC_WAY_H_
diff --git a/src/XMLParser.cpp b/src/XMLParser.cpp
index 558295c..1a20f74 100644
--- a/src/XMLParser.cpp
+++ b/src/XMLParser.cpp
@@ -1,6 +1,6 @@
 /***************************************************************************
- *   Copyright (C) 2008 by Daniel Wendt                                    *
- *   gentoo.murray at gmail.com                                               *
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -10,7 +10,7 @@
  *   This program is distributed in the hope that it will be useful,       *
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
+ *   GNU General Public License t &or more details.                        *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
@@ -18,12 +18,14 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
-#include <cstdio> 
+
+#include "./XMLParser.h"
+
 #include <errno.h>
 #include <string.h>
+#include <iostream>
+#include <cstdio>
 
-// #include "./stdafx.h"
-#include "./XMLParser.h"
 
 
 namespace xml {
@@ -31,12 +33,14 @@ namespace xml {
 //------------------------------------- global Expat Callbacks:
 
 static void startElement(void *userData, const char *name, const char **atts) {
-    XMLParserCallback* pCallback = (XMLParserCallback*) userData;
+    XMLParserCallback* pCallback =
+        reinterpret_cast<XMLParserCallback*>(userData);
     if (pCallback) pCallback->StartElement(name, atts);
 }
 
 static void endElement(void *userData, const char *name) {
-    XMLParserCallback* pCallback = (XMLParserCallback*) userData;
+    XMLParserCallback* pCallback =
+        reinterpret_cast<XMLParserCallback*>(userData);
     if (pCallback) pCallback->EndElement(name);
 }
 
@@ -50,7 +54,7 @@ int XMLParser::Parse(XMLParserCallback& rCallback, const char* chFileName) {
   if (fp) {
     XML_Parser parser = XML_ParserCreate(NULL);
 
-    XML_SetUserData(parser, (void*)&rCallback);
+    XML_SetUserData(parser, static_cast<void*>(&rCallback));
 
     // register Callbacks for start- and end-element events of the parser:
     XML_SetElementHandler(parser, startElement, endElement);
@@ -59,14 +63,15 @@ int XMLParser::Parse(XMLParserCallback& rCallback, const char* chFileName) {
     do {  // loop over whole file content
       char buf[BUFSIZ];
       size_t len = fread(buf, 1, sizeof(buf), fp);    // read chunk of data
-      done = len < sizeof(buf);    // end of file reached if buffer not completely filled
-      if (!XML_Parse(parser, buf, (int)len, done)) {
-        // a parse error occured:
-        fprintf(stderr,
-            "%s at line %d\n",
-            XML_ErrorString(XML_GetErrorCode(parser)), (int)
-            XML_GetCurrentLineNumber(parser));
-             fclose(fp);
+      // end of file reached if buffer not completely filled
+      done = len < sizeof(buf);
+      if (!XML_Parse(parser, buf, static_cast<int>(len), done)) {
+        // a parse error occurred:
+          std::cerr <<
+            XML_ErrorString(XML_GetErrorCode(parser))
+            << " at line "
+            << static_cast<int>(XML_GetCurrentLineNumber(parser));
+        fclose(fp);
         ret = 2;    // quit, return = 2 indicating parsing error
         done = 1;
       }
@@ -76,7 +81,7 @@ int XMLParser::Parse(XMLParserCallback& rCallback, const char* chFileName) {
     fclose(fp);
     ret = 0;
   } else {
-    fprintf(stderr, "Error opening %s: %s\n", chFileName, strerror(errno));
+      std::cerr <<  "Error opening " << chFileName << ":" << strerror(errno);
   }
   return ret;  // return = 0 indicating success
 }
diff --git a/src/XMLParser.h b/src/XMLParser.h
index 3f1f9af..ecef567 100644
--- a/src/XMLParser.h
+++ b/src/XMLParser.h
@@ -1,6 +1,6 @@
 /***************************************************************************
- *   Copyright (C) 2008 by Daniel Wendt                                    *
- *   gentoo.murray at gmail.com                                               *
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -10,7 +10,7 @@
  *   This program is distributed in the hope that it will be useful,       *
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
+ *   GNU General Public License t &or more details.                        *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
@@ -18,6 +18,7 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
+
 #ifndef SRC_XMLPARSER_H_
 #define SRC_XMLPARSER_H_
 
diff --git a/src/math_functions.cpp b/src/math_functions.cpp
deleted file mode 100644
index ba74843..0000000
--- a/src/math_functions.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-
-/***************************************************************************
- *   Copyright (C) 2008 by Daniel Wendt   								   *
- *   gentoo.murray at gmail.com   											   *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- ***************************************************************************/
-
-#include <math.h>
-#include "math_functions.h"
-
-#include <boost/geometry.hpp>
-#include <boost/geometry/geometries/point_xy.hpp>
-
-#if 0
-// calculation of the lenght is correct???
-double getLength(Node* a, Node* b)
-{
-	int R = 6371; //km
-	double PI =3.141592653589793238462643;
-
-	double dLat=(b->lat -a->lat)*PI/180;
-	double dLon=(b->lon -a->lon)*PI/180;
-
-	double c = sin(dLat/2) * sin(dLat/2) + cos(a->lat*PI/180) * cos(b->lat*PI/180) * sin(dLon/2) * sin(dLon/2);
-
-	double d = 2 * atan2(sqrt(c), sqrt(1-c)); 
-
-	return R*d;
-
-}
-#endif
-
-//boost fucntion to calculate the distance
-double getLength(Node* a, Node *b)
-{
-	typedef boost::geometry::model::d2::point_xy<double> point_type;
-    
-    //converted point to fit boost.geomtery (`p` and `q` are same as `a ` and `b`)
-    point_type p(a->lat , a->lon);
-    point_type q(b->lat , b->lon);
-
-    return boost::geometry::distance(p, q);
-}
diff --git a/src/math_functions.h b/src/math_functions.h
deleted file mode 100644
index f82c641..0000000
--- a/src/math_functions.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2008 by Daniel Wendt   								   *
- *   gentoo.murray at gmail.com   											   *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- ***************************************************************************/
-
-#ifndef MATH_FUNCTIONS_H
-#define MATH_FUNCTIONS_H
-
-#include "Node.h"
-
-using namespace osm2pgr;
-
-double getLength(Node* a, Node* b);
-
-
-#endif
diff --git a/src/osm2pgrouting.cpp b/src/osm2pgrouting.cpp
index 9cb19cd..ecbbd22 100644
--- a/src/osm2pgrouting.cpp
+++ b/src/osm2pgrouting.cpp
@@ -1,6 +1,6 @@
 /***************************************************************************
- *   Copyright (C) 2008 by Daniel Wendt               					   *
- *   gentoo.murray at gmail.com   											   *
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -10,39 +10,54 @@
  *   This program is distributed in the hope that it will be useful,       *
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
+ *   GNU General Public License t &or more details.                        *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
  *   Free Software Foundation, Inc.,                                       *
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
+
+#if __GNUC__ > 5 || \
+    (__GNUC__ == 4 && (__GNUC_MINOR__ >= 7))
+#define WITH_TIME
+#endif
+
 #include <unistd.h>
 #include <string>
 #include <iostream>
+
+#ifdef WITH_TIME
 #include <ctime>
 #include <chrono>
+#endif
+
 #include "./ConfigurationParserCallback.h"
-#include "./OSMDocument.h"
 #include "./OSMDocumentParserCallback.h"
+#include "./OSMDocument.h"
 #include "./Export2DB.h"
 #include "./prog_options.h"
 
 
-
 int main(int argc, char* argv[]) {
-    //  Start Timers
+#ifdef WITH_TIME
+    /*
+     *   Start Timers
+     *      version prior to 4.7.0 std::chrono::steady_clock was not implemented.
+     *      so using timers work on g++4.7 up
+     */
     clock_t begin = clock();
     std::time_t start_t = std::time(NULL);
-    std::chrono::steady_clock::time_point begin_elapsed = std::chrono::steady_clock::now();
+    std::chrono::steady_clock::time_point begin_elapsed =
+        std::chrono::steady_clock::now();
+#endif
     try {
-
         po::options_description od_desc("Allowed options");
         get_option_description(od_desc);
 
         po::variables_map vm;
         po::store(po::command_line_parser(argc, argv).
-            options(od_desc).run(), vm);
+                options(od_desc).run(), vm);
 
         if (vm.count("help")) {
             std::cout << od_desc << "\n";
@@ -50,7 +65,7 @@ int main(int argc, char* argv[]) {
         }
 
         if (vm.count("version")) {
-            std::cout << "This is osm2pgrouting Version 2.1\n";
+            std::cout << "This is osm2pgrouting Version 2.2\n";
             return 0;
         }
 
@@ -64,7 +79,9 @@ int main(int argc, char* argv[]) {
             return 0;
         }
 
+#ifdef WITH_TIME
         std::cout << "Execution starts at: " << std::ctime(&start_t) << "\n";
+#endif
         process_command_line(vm);
 
         auto dataFile(vm["file"].as<string>());
@@ -74,104 +91,117 @@ int main(int argc, char* argv[]) {
 
 
         std::cout << "Connecting to the database"  << endl;
-            Export2DB dbConnection(vm);
-            if (dbConnection.connect() == 1)
-                return 1;
-            if (!dbConnection.has_postGIS()) {
-                std::cout << "ERROR: postGIS not found\n";
-                return 1;
-            }
+        osm2pgr::Export2DB dbConnection(vm);
+        if (dbConnection.connect() == 1)
+            return 1;
+        if (!dbConnection.has_postGIS()) {
+            std::cout << "ERROR: postGIS not found\n";
+            return 1;
+        }
 
 
         std::cout << "Opening configuration file: " << confFile.c_str() << endl;
-            Configuration* config = new Configuration();
-            ConfigurationParserCallback cCallback(*config);
+        osm2pgr::Configuration config;
+        osm2pgr::ConfigurationParserCallback cCallback(config);
 
 
         std::cout << "    Parsing configuration\n" << endl;
-            xml::XMLParser parser;
-            int ret = parser.Parse(cCallback, confFile.c_str());
-            if (ret != 0) {
-                cout << "Failed to open / parse config file " << confFile.c_str() << endl;
-                return 1;
-            }
+        xml::XMLParser parser;
+        int ret = parser.Parse(cCallback, confFile.c_str());
+        if (ret != 0) {
+            cout << "Failed to open / parse config file "
+                << confFile.c_str()
+                << endl;
+            return 1;
+        }
 
+        size_t total_lines = 100000;
 
-        std::cout << "Opening data file: " << dataFile.c_str() << endl;
-            OSMDocument *document = new OSMDocument(*config);
-            OSMDocumentParserCallback callback(*document);
+        osm2pgr::OSMDocument document(config, total_lines);
+        osm2pgr::OSMDocumentParserCallback callback(document);
 
-        std::cout << "    Parsing data\n" << endl;
+        std::cout << "    Parsing data (progress line per " << total_lines << " elements)\n" << endl;
         ret = parser.Parse(callback, dataFile.c_str());
         if (ret != 0) {
-            cerr << "Failed to open / parse data file " << dataFile.c_str() << endl;
+            cerr << "Failed to open / parse data file " << dataFile << endl;
             return 1;
         }
-
-        std::cout << "Spliting ways\n" << endl;
-            document->SplitWays();
+        std::cout << "    Finish Parsing data\n" << endl;
+        if (document.nodesErrs()) {
+            std::cerr << "******\nNOTICE:  Found " << document.nodesErrs() << " node references with no <node ... >\n*****";
+        }
 
         //############# Export2DB
-        { 
-        if (clean) {
-            std::cout << "Dropping tables..." << endl;
-            dbConnection.dropTables();
-        }
+        {
+            if (clean) {
+                std::cout << "\nDropping tables..." << endl;
+                dbConnection.dropTables();
+            }
 
-        std::cout << "Creating tables..." << endl;
+            std::cout << "\nCreating tables..." << endl;
             dbConnection.createTables();
 
-        std::cout << "Adding auxiliary tables to database..." << endl;
+            std::cout << "Adding auxiliary tables to database..." << endl;
             if (!skipnodes) {
-                dbConnection.exportNodes(document->m_Nodes);
+                std::cout << "\nExport Nodes ..." << endl;
+                dbConnection.exportNodes(document.nodes());
             }
-            dbConnection.exportTypes(config->m_Types);
-            dbConnection.exportClasses(config->m_Types);
-            //dbConnection.exportRelations(document->m_Relations, config);
-            dbConnection.exportRelationsWays(document->m_Relations);
-            dbConnection.exportTags(document->m_SplittedWays, config);
-            dbConnection.exportWays(document->m_SplittedWays, config);
-
-
-            std::cout << "Creating topology..." << endl;
-            dbConnection.createTopology();
+            std::cout << "\nExport Types ..." << endl;
+            dbConnection.exportTypes(config.types());
+            std::cout << "\nExport Classes ..." << endl;
+            dbConnection.exportClasses(config.types());
+            std::cout << "\nExport Relations ..." << endl;
+            dbConnection.exportRelations(document.relations(), config);
+            std::cout << "\nExport RelationsWays ..." << endl;
+            dbConnection.exportRelationsWays(document.relations(), config);
+            std::cout << "\nExport Ways ..." << endl;
+            dbConnection.exportWays(document.ways(), config);
+
+
+            std::cout << "Creating Foreign Keys ..." << endl;
+            dbConnection.createFKeys();
         }
 
 
         std::cout << "#########################" << endl;
 
-        std::cout << "size of streets: " << document->m_Ways.size() <<    endl;
-        std::cout << "size of splitted ways : " << document->m_SplittedWays.size() <<    endl;
+        std::cout << "size of streets: " << document.ways().size() << endl;
 
+#ifdef WITH_TIME
         clock_t end = clock();
-        double elapsed_secs = double(end - begin) / static_cast<double>(CLOCKS_PER_SEC);
+        double elapsed_secs =
+            static_cast<double>(end - begin)
+            / static_cast<double>(CLOCKS_PER_SEC);
 
         std::time_t end_t = std::time(NULL);
-        std::chrono::steady_clock::time_point end_elapsed = std::chrono::steady_clock::now();
+        std::chrono::steady_clock::time_point end_elapsed =
+            std::chrono::steady_clock::now();
 
-        typedef std::chrono::duration<int,std::milli> millisecs_t ;
-        millisecs_t duration = std::chrono::duration_cast<millisecs_t>(end_elapsed - begin_elapsed);
+        typedef std::chrono::duration<int, std::milli> millisecs_t;
+        millisecs_t duration = std::chrono::duration_cast<millisecs_t>(
+                end_elapsed - begin_elapsed);
 
         std::cout << "Execution started at: " << std::ctime(&start_t);
         std::cout << "Execution ended at:   " << std::ctime(&end_t);
-        std::cout << "Elapsed time: " << (double)duration.count()/(double)1000 << " Seconds.\n" ;
+        std::cout << "Elapsed time: "
+            << static_cast<double>(duration.count())/static_cast<double>(1000)
+            << " Seconds.\n";
         std::cout << "User CPU time: -> " << elapsed_secs << " seconds\n";
-        
+#endif
+
         std::cout << "#########################" << endl;
-        //  string n;
-        //  getline(cin, n);
         return 0;
     }
     catch (exception &e) {
         std::cout << e.what() << endl;
         return 1;
-    } 
+    }
     catch (string &e) {
         std::cout << e << endl;
         return 1;
-    } 
+    }
     catch (...) {
         std::cout << "Terminating" << endl;
         return 1;
-    } 
+    }
 }
diff --git a/src/osm_element.cpp b/src/osm_element.cpp
new file mode 100644
index 0000000..1b61c26
--- /dev/null
+++ b/src/osm_element.cpp
@@ -0,0 +1,105 @@
+/***************************************************************************
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License t &or more details.                        *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+
+#include <boost/lexical_cast.hpp>
+#include <map>
+#include <string>
+#include "./osm_tag.h"
+#include "./osm_element.h"
+
+namespace osm2pgr {
+
+
+Element::Element(const char **atts) :
+    m_visible(true) {
+        auto **attribut = atts;
+        while (*attribut != NULL) {
+            std::string name = *attribut++;
+            std::string value = *attribut++;
+            if (name == "id") {
+                m_osm_id = boost::lexical_cast<int64_t>(value);
+            }
+            if (name == "visible") {
+                m_visible = (value == "true")? true : false;
+            }
+            m_attributes[name] = value;
+        }
+    }
+
+Tag
+    Element::add_tag(const Tag &tag) {
+        m_tags[tag.key()] = tag.value();
+        return tag;
+    }
+
+bool
+    Element::has_tag(const std::string& key) const {
+        return m_tags.find(key) != m_tags.end();
+    }
+
+std::string
+    Element::get_tag(const std::string& key) const {
+        return m_tags.find(key)->second;
+    }
+
+bool
+    Element::has_attribute(const std::string& key) const {
+        return m_attributes.find(key) != m_attributes.end();
+    }
+
+std::string
+    Element::get_attribute(const std::string& key) const {
+        return m_attributes.find(key)->second;
+    }
+
+std::string Element::attributes_str() const {
+    if (m_tags.empty()) return "\"\"";
+    std::string str("\"");
+    for (auto it = m_attributes.begin(); it != m_attributes.end(); ++it) {
+        auto attribute = *it;
+        str +=  attribute.first + "=>" + attribute.second + ",";
+    }
+#if 0
+    str.pop_back();
+    str += "\"";
+#else
+    str[str.size()-1] = '\"';
+#endif
+    return str;
+}
+
+std::string Element::tags_str() const {
+    if (m_tags.empty()) return "";
+    std::string str("\"");
+    for (auto it = m_tags.begin(); it != m_tags.end(); ++it) {
+        auto tag = *it;
+        str +=  tag.first + "=>" + tag.second + ",";
+    }
+#if 0
+    str.pop_back();
+    str += "\"";
+#else
+    str[str.size()-1] = '\"';
+#endif
+    return str;
+}
+
+}  // namespace osm2pgr
diff --git a/src/osm_element.h b/src/osm_element.h
new file mode 100644
index 0000000..7007a86
--- /dev/null
+++ b/src/osm_element.h
@@ -0,0 +1,92 @@
+/***************************************************************************
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License t &or more details.                        *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+
+#ifndef SRC_OSM_ELEMENT_H_
+#define SRC_OSM_ELEMENT_H_
+#pragma once
+
+#include <string>
+#include <map>
+#include "./osm_tag.h"
+
+namespace osm2pgr {
+
+
+    /** @brief osm elements
+
+      osm elements can be:
+
+      @code
+      <node
+      <way
+      <relation
+      @endcode
+
+      */
+
+class Element {
+ public:
+     Element() = default;
+     Element(const Element&) = default;
+     /**
+      *    Constructor
+      *    @param atts attributes pointer returned by the XML parser
+      */
+     explicit Element(const char **atts);
+     Tag add_tag(const Tag &);
+
+     inline int64_t osm_id() const {return m_osm_id;}
+     inline bool visible() const {return m_visible;}
+     inline void tag_config(const Tag &tag) {m_tag_config = tag;}
+     inline Tag tag_config() const {return m_tag_config;}
+
+
+
+     std::string attributes_str() const;
+     std::string tags_str() const;
+
+     bool has_attribute(const std::string&) const;
+     std::string get_attribute(const std::string&) const;
+     std::map<std::string, std::string>& attributes() {return m_attributes;}
+     const std::map<std::string, std::string> attributes() const {
+         return m_attributes;
+     }
+
+
+     bool has_tag(const std::string&) const;
+     std::string get_tag(const std::string&) const;
+     std::map<std::string, std::string>& tags() {return m_tags;}
+     const std::map<std::string, std::string> tags() const {return m_tags;}
+
+ protected:
+     // ! OSM ID of the element
+     int64_t m_osm_id;
+     bool m_visible;
+     Tag m_tag_config;
+
+
+     std::map<std::string, std::string> m_tags;
+     std::map<std::string, std::string> m_attributes;
+};
+
+
+}  // namespace osm2pgr
+#endif  // SRC_OSM_ELEMENT_H_
diff --git a/src/Relation.cpp b/src/osm_tag.cpp
similarity index 65%
copy from src/Relation.cpp
copy to src/osm_tag.cpp
index c46a0a1..6d7cf55 100644
--- a/src/Relation.cpp
+++ b/src/osm_tag.cpp
@@ -1,6 +1,6 @@
 /***************************************************************************
- *   Copyright (C) 2008 by Daniel Wendt   								   *
- *   gentoo.murray at gmail.com   											   *
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -10,35 +10,37 @@
  *   This program is distributed in the hope that it will be useful,       *
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
+ *   GNU General Public License t &or more details.                        *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
  *   Free Software Foundation, Inc.,                                       *
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
-#include <string>
-#include "./Relation.h"
-//#include "./Way.h"
 
 
-namespace osm2pgr {
+#include "./osm_tag.h"
+#include <string>
 
-Relation::Relation(int64_t id)
-:
-    id(id) {
-}
+namespace osm2pgr {
 
-Relation::~Relation() {
-}
 
-void Relation::AddWayRef(int64_t pID) {
-    if (pID) m_WayRefs.push_back(pID);
+Tag::Tag(const char **atts) {
+    auto **attribut = atts;
+    while (*attribut != NULL) {
+        std::string name = *attribut++;
+        std::string value = *attribut++;
+        if (name  == "k") {
+            m_key = value;
+        } else if (name == "v") {
+            m_value = value;
+        }
+    }
 }
 
-void Relation::AddTag(std::string key, std::string value) {
-    m_Tags[key] = value;
+std::ostream& operator<<(std::ostream &os, const Tag& tag) {
+    os << tag.m_key << "=>" << tag.m_value;
+    return os;
 }
 
-}  // end namespace osm2pgr
-
+}  // namespace osm2pgr
diff --git a/src/Relation.h b/src/osm_tag.h
similarity index 50%
copy from src/Relation.h
copy to src/osm_tag.h
index ecfb77e..676f2f7 100644
--- a/src/Relation.h
+++ b/src/osm_tag.h
@@ -1,6 +1,6 @@
 /***************************************************************************
- *   Copyright (C) 2008 by Daniel Wendt                                    *
- *   gentoo.murray at gmail.com                                               *
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -10,66 +10,69 @@
  *   This program is distributed in the hope that it will be useful,       *
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
+ *   GNU General Public License t &or more details.                        *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
  *   Free Software Foundation, Inc.,                                       *
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
-#ifndef SRC_RELATION_H_
-#define SRC_RELATION_H_
 
-#include <vector>
-#include <map>
+
+#ifndef SRC_OSM_TAG_H_
+#define SRC_OSM_TAG_H_
+#pragma once
+
+#include <boost/lexical_cast.hpp>
+#include <cstdint>
 #include <string>
+#include <map>
+
 
 namespace osm2pgr {
-class Way;
+
 
 /**
-\code
- <way id="20215432" visible="true" timestamp="2008-01-09T22:35:16+00:00" user="Pferdo">
-    <nd ref="213794929"/>
-    <nd ref="213795470"/>
-    <nd ref="213795483"/>
-    <nd ref="213795493"/>
-    <nd ref="213795506"/>
-    <nd ref="213795517"/>
-    <nd ref="213795527"/>
-    <nd ref="213795541"/>
-    <nd ref="213795552"/>
-    <nd ref="213795561"/>
-    <nd ref="213795571"/>
-    <tag k="name" v="Pf�nderweg"/>
-    <tag k="created_by" v="JOSM"/>
-    <tag k="highway" v="residential"/>
-  </way>
-\endcode
-*/
-class Relation {
- public:
-    long long id;
-    std::string name;
-    std::vector<int64_t> m_WayRefs;
-    std::map<std::string, std::string> m_Tags;
+  @code
+  <tag k="highway" v="crossing"/>
+  <tag k="exit_to" v="OR 217;Tigard;Salem"/>
+  <tag k="highway" v="motorway_junction"/>
+  <tag k="ref" v="69A"/>
+  <tag k="name" v="Southwest Park & Market"/>
+  <tag k="public_transport" v="stop_position"/>
+  <tag k="railway" v="tram_stop"/>
+  <tag k="ref" v="11011"/>
+  <tag k="tram" v="yes"/>
+  <tag k="highway" v="turning_circle"/>
+
+  @endcode
+  */
 
+class Tag {
  public:
-    /** 
-     *    Constructor
-     *    @param id ID of the way
-     */
-    Relation(int64_t id);
-    //! Destructor
-    ~Relation();
-    /**
-     *    saves the nodes of the way  
-     *    @param pNode node
-     */
-    void AddWayRef(int64_t pID);
-    void AddTag(std::string key, std::string value);
+     Tag() = default;
+     Tag(const Tag&) = default;
+     /**
+      *    Constructor
+      *    @param atts attributes pointer returned by the XML parser
+      */
+     explicit Tag(const char **atts);
+     Tag(const std::string &k, const std::string &v) {
+         m_key = k;
+         m_value = v;
+     }
+
+     inline std::string key() const {return m_key;}
+     inline std::string value() const {return m_value;}
+     friend std::ostream& operator<<(std::ostream &os, const Tag& tag);
+
+ private:
+     // ! key
+     std::string m_key;
+     // ! value
+     std::string m_value;
 };
 
 
 }  // end namespace osm2pgr
-#endif  // SRC_RELATION_H_
+#endif  // SRC_OSM_TAG_H_
diff --git a/src/Way.cpp b/src/print_progress.h
similarity index 57%
copy from src/Way.cpp
copy to src/print_progress.h
index 9a908af..709c0ff 100644
--- a/src/Way.cpp
+++ b/src/print_progress.h
@@ -1,6 +1,6 @@
 /***************************************************************************
- *   Copyright (C) 2008 by Daniel Wendt   								   *
- *   gentoo.murray at gmail.com   											   *
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -10,7 +10,7 @@
  *   This program is distributed in the hope that it will be useful,       *
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
+ *   GNU General Public License t &or more details.                        *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
@@ -18,45 +18,35 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
-#include <string>
-#include "Way.h"
-
-
-namespace osm2pgr {
-
-Way::Way(int64_t id, bool visible, int64_t osm_id, int maxspeed_forward, int maxspeed_backward)
-:
-	id(id),
-	visible(visible),
-	length(0),
-	maxspeed_forward(maxspeed_forward),
-	maxspeed_backward(maxspeed_backward),
-	oneWayType(UNKNOWN),
-	osm_id(osm_id) {
-}
-
-#if 0
-Way::~Way()
-{
-}
-#endif
+#ifndef SRC_PRINT_PROGRESS_H_
+#define SRC_PRINT_PROGRESS_H_
+#pragma once
 
-void Way::AddNodeRef( Node* pNode )
-{
-	if( pNode ) m_NodeRefs.push_back(pNode);
-}
 
-void Way::AddTag( std::string key , std::string value)
-{
-	m_Tags[key] = value;
-}
+#include <iostream>
+#include <string>
 
-bool Way::HasTag(std::string key)
-{
-	return (m_Tags.count(key)>0);
+template < typename T1 , typename T2>
+void
+print_progress(T1 wantProgress, T2 currentProgress) {
+    int length = 50;
+    double percent = static_cast <double> (currentProgress) /  static_cast <double>(wantProgress);
+    int fillerLength = static_cast<int>(percent * length);
+
+    std::string bar = "[";
+    for (int i = 0; i < fillerLength; i++) {
+        bar += "*";
+    }
+
+    bar += "|";
+    for (int i = 0; i < length - fillerLength; i++) {
+        bar += " ";
+    }
+
+    bar += "]";
+    std::cout << "\r"
+        << bar
+        << " (" << static_cast<int>(100 * percent) << "%)"
+        << std::flush;
 }
-
-
-
-} // end namespace osm2pgr
-
+#endif  // SRC_PRINT_PROGRESS_H_
diff --git a/src/prog_options.cpp b/src/prog_options.cpp
index bbd94b0..55c89ad 100644
--- a/src/prog_options.cpp
+++ b/src/prog_options.cpp
@@ -1,28 +1,23 @@
-/*osm2pgRouting
+/***************************************************************************
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License t &or more details.                        *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
 
-Copyright (c) 2015 Sarthak Agarwal
-sarthak0415 at gmail.com
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-*/
-
-/*to compile and run
->>  g++ prog_options.cpp -o a -lboost_program_options -g -O3 -std=c++0x -Wall -pedantic
->> ./a --help
-*/
 
 #include <boost/program_options.hpp>
 #include <boost/config.hpp>
@@ -33,8 +28,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 #include <string>
 namespace po = boost::program_options;
 
-using namespace std;
-
 
 void get_option_description(po::options_description &od_desc) {
     /* po::options_description help_od_desc("Help"),
@@ -49,35 +42,30 @@ void get_option_description(po::options_description &od_desc) {
     help_od_desc.add_options()
         // help
         ("help", "Produce help message for this version.")
-        ("version,v", "Print version string")
-        ;
+        ("version,v", "Print version string");
 
     general_od_desc.add_options()
         // general
-        ("file,f", po::value<string>()->required(), "REQUIRED: Name of the osm file.")
-        ("conf,c", po::value<string>()->default_value("/usr/share/osm2pgrouting/mapconfig.xml"), "Name of the configuration xml file.")
-        //("conf,c", po::value<string>()->required()->default_value("/usr/share/osm2pgrouting/mapconfig.xml"), "Name of the configuration xml file.")
-        ("schema", po::value<string>()->default_value(""), "Database schema to put tables.\n  blank:\t defaults to default schema dictated by PostgreSQL search_path.")
-        ("prefix", po::value<string>()->default_value(""), "Prefix added at the beginning of the table names.")
-        ("suffix", po::value<string>()->default_value(""), "Suffix added at the end of the table names.")
+        ("file,f", po::value<std::string>()->required(), "REQUIRED: Name of the osm file.")
+        ("conf,c", po::value<std::string>()->default_value("/usr/share/osm2pgrouting/mapconfig.xml"), "Name of the configuration xml file.")
+        ("schema", po::value<std::string>()->default_value(""), "Database schema to put tables.\n  blank:\t defaults to default schema dictated by PostgreSQL search_path.")
+        ("prefix", po::value<std::string>()->default_value(""), "Prefix added at the beginning of the table names.")
+        ("suffix", po::value<std::string>()->default_value(""), "Suffix added at the end of the table names.")
         ("addnodes", "Import the osm_nodes table.")
-        ("clean", "Drop previously created tables.")
-        ;
+        ("clean", "Drop previously created tables.");
 
     db_options_od_desc.add_options()
         // database options
-        ("dbname,d", po::value<string>()->required(), "Name of your database (Required).")
-        ("username,U", po::value<string>()->default_value("postgres"), "Name of the user, which have write access to the database.")
-        ("host,h", po::value<string>()->default_value("localhost"), "Host of your postgresql database.")
-        ("port,p", po::value<string>()->default_value("5432"), "db_port of your database.")
-        ("password,W", po::value<string>()->default_value(""), "Password for database access.")
-        ;
+        ("dbname,d", po::value<std::string>()->required(), "Name of your database (Required).")
+        ("username,U", po::value<std::string>()->default_value("postgres"), "Name of the user, which have write access to the database.")
+        ("host,h", po::value<std::string>()->default_value("localhost"), "Host of your postgresql database.")
+        ("port,p", po::value<std::string>()->default_value("5432"), "db_port of your database.")
+        ("password,W", po::value<std::string>()->default_value(""), "Password for database access.");
 
     not_used_od_desc.add_options()
         ("threads,t", po::value<bool>()->default_value(false), "threads.")
         ("multimodal,m", po::value<bool>()->default_value(false), "multimodal.")
-        ("multilevel,l", po::value<bool>()->default_value(false), "multilevel.")
-        ;
+        ("multilevel,l", po::value<bool>()->default_value(false), "multilevel.");
 
     od_desc.add(help_od_desc).add(general_od_desc).add(db_options_od_desc);  // .add(not_used_od_desc);
 
@@ -87,20 +75,20 @@ void get_option_description(po::options_description &od_desc) {
 
 
 void
-process_command_line( po::variables_map &vm) {
+process_command_line(po::variables_map &vm) {
     std::cout << "***************************************************\n";
     std::cout << "           COMMAND LINE CONFIGURATION             *\n";
     std::cout << "***************************************************\n";
-    std::cout << "Filename = " << vm["file"].as<string>() << "\n";
-    std::cout << "Configuration file = " << vm["conf"].as<string>() << "\n";
+    std::cout << "Filename = " << vm["file"].as<std::string>() << "\n";
+    std::cout << "Configuration file = " << vm["conf"].as<std::string>() << "\n";
     std::cout << "host = " << vm["host"].as<std::string>() << "\n";
     std::cout << "port = " << vm["port"].as<std::string>() << "\n";
     std::cout << "dbname = " << vm["dbname"].as<std::string>() << "\n";
     std::cout << "username = " << vm["username"].as<std::string>() << "\n";
-    std::cout << "password = " << vm["password"].as<string>() << "\n";
-    std::cout << "schema= " << vm["schema"].as<string>() << "\n";
-    std::cout << "prefix = " << vm["prefix"].as<string>() << "\n";
-    std::cout << "suffix = " << vm["suffix"].as<string>() << "\n";
+    std::cout << "password = " << vm["password"].as<std::string>() << "\n";
+    std::cout << "schema= " << vm["schema"].as<std::string>() << "\n";
+    std::cout << "prefix = " << vm["prefix"].as<std::string>() << "\n";
+    std::cout << "suffix = " << vm["suffix"].as<std::string>() << "\n";
     std::cout << (vm.count("clean")? "D" : "Don't d") << "rop tables\n";
     std::cout << (vm.count("addnodes")? "A" : "Don't a") << "dd nodes\n";
     std::cout << "***************************************************\n";
diff --git a/src/prog_options.h b/src/prog_options.h
index 90460d2..4b13c3a 100644
--- a/src/prog_options.h
+++ b/src/prog_options.h
@@ -1,21 +1,24 @@
-/*PGR
-Copyright (c) 2015 (your full name)
-(your main e mail address)
+/***************************************************************************
+ *   Copyright (C) 2016 by pgRouting developers                            *
+ *   project at pgrouting.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License t &or more details.                        *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
 
 
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
 #ifndef SRC_PROG_OPTIONS_H_
 #define SRC_PROG_OPTIONS_H_
 
diff --git a/src/utils.cpp b/src/utils.cpp
deleted file mode 100644
index 55e0358..0000000
--- a/src/utils.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-#include "utils.h"
-
-namespace my_utils{
-
-bool is_number(const std::string& s)
-{
-	std::string::const_iterator it = s.begin();
-	while (it != s.end() && std::isdigit(*it)) ++it;
-	return !s.empty() && it == s.end();
-}
-
-
-/**
- * Read first 5 digits from a string.
- */
-std::string read_number_substring(const std::string& s)
-{
-	char buffer[5];
-	int index = 0;
-	std::string::const_iterator it = s.begin();
-	while (it < s.end() && std::isdigit(*it) && index < 5){
-		buffer[index] = *it;
-		++index;
-		++it;
-	}
-	buffer[index] = 0;
-	std::string out( buffer );
-	return out;
-}
-
-}
diff --git a/src/utils.h b/src/utils.h
deleted file mode 100644
index e41a87a..0000000
--- a/src/utils.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#include <string>
-
-namespace my_utils{
-
-bool is_number(const std::string& s);
-
-std::string read_number_substring(const std::string& s);
-
-}
diff --git a/tools/initial_commit.txt b/tools/initial_commit.txt
new file mode 100644
index 0000000..47c09d8
--- /dev/null
+++ b/tools/initial_commit.txt
@@ -0,0 +1 @@
+https://github.com/pgRouting/osm2pgrouting/tree/88372f829877f4c5ed4def7e395ddfd5316944dc
diff --git a/tools/spelling/fix_typos.sh b/tools/spelling/fix_typos.sh
new file mode 100755
index 0000000..3c4dbc8
--- /dev/null
+++ b/tools/spelling/fix_typos.sh
@@ -0,0 +1,67 @@
+#!/bin/sh
+# -*- coding: utf-8 -*-
+###############################################################################
+# $Id$
+#
+#  Project:  GDAL
+#  Purpose:  (Interactive) script to identify and fix typos
+#  Author:   Even Rouault <even.rouault at spatialys.com>
+#
+###############################################################################
+#  Copyright (c) 2016, Even Rouault <even.rouault at spatialys.com>
+#
+#  Permission is hereby granted, free of charge, to any person obtaining a
+#  copy of this software and associated documentation files (the "Software"),
+#  to deal in the Software without restriction, including without limitation
+#  the rights to use, copy, modify, merge, publish, distribute, sublicense,
+#  and/or sell copies of the Software, and to permit persons to whom the
+#  Software is furnished to do so, subject to the following conditions:
+#
+#  The above copyright notice and this permission notice shall be included
+#  in all copies or substantial portions of the Software.
+#
+#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+#  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+#  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+#  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+#  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+#  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+#  DEALINGS IN THE SOFTWARE.
+###############################################################################
+
+if ! test -d fix_typos; then
+    # Get our fork of codespell that adds --words-white-list and full filename support for -S option
+    mkdir fix_typos
+    cd fix_typos
+    git clone https://github.com/rouault/codespell
+    cd codespell
+    git checkout gdal_improvements
+    cd ..
+    # Aggregate base dictionary + QGIS one + Debian Lintian one
+    curl https://raw.githubusercontent.com/qgis/QGIS/master/scripts/spelling.dat | sed "s/:/->/" | grep -v "colour->" | grep -v "colours->" > qgis.txt
+    curl https://anonscm.debian.org/cgit/lintian/lintian.git/plain/data/spelling/corrections| grep "||" | grep -v "#" | sed "s/||/->/" > debian.txt
+    cat codespell/data/dictionary.txt qgis.txt debian.txt | awk 'NF' > gdal_dict.txt
+    echo "difered->deferred" >> gdal_dict.txt
+    echo "differed->deferred" >> gdal_dict.txt
+    cd ..
+fi
+
+EXCLUDED_FILES="$EXCLUDED_FILES,*/fix_typos/*,*/build/*"
+EXCLUDED_FILES="$EXCLUDED_FILES,*/.git/*"
+EXCLUDED_FILES="$EXCLUDED_FILES,*/tools/*"
+
+#WORDS_WHITE_LIST="poSession,FIDN,TRAFIC,HTINK,repID,oCurr,INTREST,oPosition"
+#WORDS_WHITE_LIST="$WORDS_WHITE_LIST,CPL_SUPRESS_CPLUSPLUS,SRP_NAM,ADRG_NAM,'SRP_NAM,AuxilaryTarget"
+# IRIS driver metadata item names: FIXME ?
+#WORDS_WHITE_LIST="$WORDS_WHITE_LIST,TOP_OF_HEIGTH_INTERVAL,BOTTOM_OF_HEIGTH_INTERVAL"
+# libjpeg
+#WORDS_WHITE_LIST="$WORDS_WHITE_LIST,JBUF_PASS_THRU"
+# libgif
+#WORDS_WHITE_LIST="$WORDS_WHITE_LIST,IS_WRITEABLE,E_GIF_ERR_NOT_WRITEABLE"
+# libtiff
+#WORDS_WHITE_LIST="$WORDS_WHITE_LIST,THRESHHOLD_BILEVEL,THRESHHOLD_HALFTONE,THRESHHOLD_ERRORDIFFUSE"
+
+python3 fix_typos/codespell/codespell.py -w -i 3 -q 2 -S $EXCLUDED_FILES \
+    -x tools/spelling/typos_whitelist.txt --words-white-list=$WORDS_WHITE_LIST \
+    -D fix_typos/gdal_dict.txt  .
+
diff --git a/tools/spelling/typos_whitelist.txt b/tools/spelling/typos_whitelist.txt
new file mode 100644
index 0000000..2812cb9
--- /dev/null
+++ b/tools/spelling/typos_whitelist.txt
@@ -0,0 +1,39 @@
+    // FIXME: is it a typo here or in IRIS itself: Perspective or Prespective ?
+    "Prespective from geosync","Equidistant cylindrical","Gnomonic",
+   /* 160 */ {"Bas_St_Wol", "Untergrenze strat. Bew|lkung", "hft", UC_NONE},
+   /* 161 */ {"Bas_St_Wol", "Untergrenze strat. Bew|lkung", "hPa", UC_NONE},
+   /* 164 */ {"Top_St_Wol", "Obergrenze strat. Bew|lkung", "hft", UC_NONE},
+   /* 165 */ {"Top_St_Wol", "Obergrenze strat. Bew|lkung", "hPa", UC_NONE},
+              "Icing Regime 1.Guess(1=gen,2=conv,3=strat,4=freez)", "1",
+              "Icing Regime(1=general,2=convect,3=strat,4=freez)", "1",
+ * The generated swig_type_info structures are assigned staticly to an initial 
+ * The generated swig_type_info structures are assigned staticly to an initial
+            YUR = 0.0;
+            YUR = oES.YUR;
+        double YUR;
+    l_segment->YUR = seg_data.GetDouble(nPos+215, 22);
+    seg_data.Put(psOrbit->YUR,nPos+215,22,"%22.14f");
+/* Putting statics in headers is trouble. */
+See COMMITERS file. 
+  /* When multiple interpeters are used, a module could have already been initialized in
+    const char* pszNAM = record->GetStringSubfield("DSI", 0, "NAM", 0);
+                    const char* pszNAM = record->GetStringSubfield("FDR", iFDRFieldInstance++, "NAM", 0);
+                                                "PRT!NAM",
+    sizeOfFields[nFields] += WriteSubFieldStr(fd, osBaseFileName, 8); /* NAM */
+    sizeOfFields[nFields] += WriteSubFieldStr(fd, osNAM.c_str(), 8); /* NAM */
+                                                  "NAM!STR!PRT!SWO!SWA!NEO!NEA",
+        sizeOfFields[nFields] += WriteSubFieldStr(fd, osBaseFileName, 8); /* NAM */
+      {136, "Socialist Republic of Viet Nam"},
+        double  eps[NANGLES], ua, va, ang, epsa;
+                ang = uv2ang(ua, va);
+                i = (int) ang;
+                epsa = fabs(ang - (i+.5));
+                "     UN=Metres,SD=HHWLT,DX=2.500000,DY=2.500000\n");
+        pszUnitsPer = CPLGetXMLValue( psSrcXML, "metresPerUnit", NULL );
+    {"kilometre",    /* 15 */ 12,  13,  1000.0},
+                    oSRS.SetLinearUnits( "kilometre", 1000.0 );
+{ "kilometre", SRS_UL_KILOMETER_CONV, "km" }, // Leave as 'kilometre' instead of SRS_UL_KILOMETER due to historical usage
+            passport.stMapDescription.eUnitInPlan = SXF_COORD_MU_CENTIMETRE;
+            passport.stMapDescription.eUnitInPlan = SXF_COORD_MU_MILLIMETRE;
+    SXF_COORD_MU_CENTIMETRE,
+    SXF_COORD_MU_MILLIMETRE,
diff --git a/tools/vagrant/bootstrap.sh b/tools/vagrant/bootstrap.sh
deleted file mode 100755
index 55f965c..0000000
--- a/tools/vagrant/bootstrap.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/bash
-# ------------------------------------------------------------------------------
-# Vagrant - Virtualized Development 
-# Copyright(c) pgRouting Contributors
-#
-# Virtual environment bootstrap script
-# ------------------------------------------------------------------------------
-
-set -e # Exit script immediately on first error.
-#set -x # Print commands and their arguments as they are executed.
-
-# Abort provisioning if pgRouting development environment already setup.
-# ------------------------------------------------------------------------------
-which vim >/dev/null &&
-{ echo "osm2pgrouting development environment already setup."; exit 0; }
-
-# Run provisioning
-# ------------------------------------------------------------------------------
-echo "Installing packages ... this may take some time."
-apt-get update -qq
-apt-get install -y -qq vim packaging-dev checkinstall libboost-graph-dev libpq-dev libexpat1-dev
-
diff --git a/tools/vagrant/packaging.sh b/tools/vagrant/packaging.sh
deleted file mode 100755
index 419de7c..0000000
--- a/tools/vagrant/packaging.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-# ------------------------------------------------------------------------------
-# Vagrant - Virtualized Development 
-# Copyright(c) pgRouting Contributors
-#
-# Prepare packaging (sample)
-# ------------------------------------------------------------------------------
-
-echo "DEBEMAIL=daniel at georepublic.de" > ~/.bash_aliases
-echo "DEBFULLNAME='Daniel Kastl (Georepublic)'" >> ~/.bash_aliases
-
-git config --global user.name "Daniel Kastl"
-git config --global user.email "daniel at georepublic.de"
-git config --global core.editor vim
-git config --global color.ui true
diff --git a/tools/vagrant/packaging.sh.sample b/tools/vagrant/packaging.sh.sample
deleted file mode 100755
index 0ebdf38..0000000
--- a/tools/vagrant/packaging.sh.sample
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-# ------------------------------------------------------------------------------
-# Vagrant - Virtualized Development 
-# Copyright(c) pgRouting Contributors
-#
-# Prepare packaging (sample)
-# ------------------------------------------------------------------------------
-
-echo "DEBEMAIL=mail at example.com" > ~/.bash_aliases
-echo "DEBFULLNAME='First Last'" >> ~/.bash_aliases
-
-git config --global user.name "First Last"
-git config --global user.email "mail at example.com"
-git config --global core.editor vim
-git config --global color.ui true

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/osm2pgrouting.git



More information about the Pkg-grass-devel mailing list