[osm2pgrouting] 02/08: New upstream version 2.3.0

Bas Couwenberg sebastic at debian.org
Wed Oct 11 16:51:11 UTC 2017


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

sebastic pushed a commit to branch master
in repository osm2pgrouting.

commit 916b7c024802bc36370ff67d32adf98fbb5125ed
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Wed Oct 11 18:17:30 2017 +0200

    New upstream version 2.3.0
---
 .gitignore                                         |   1 +
 .travis.yml                                        |  22 +-
 AUTHORS.md                                         |   1 +
 CMakeLists.txt                                     |  33 +-
 NEWS                                               |   9 +
 Readme.md                                          |  29 +-
 ci/travis/install-libpqxx.sh                       |  26 +
 ci/travis/osm2pgrouting_build.sh                   |   8 +-
 cmake/FindLibPQXX.cmake                            |  43 +
 include/configuration/configuration.h              |  99 +++
 src/Type.h => include/configuration/tag_key.h      |  50 +-
 src/Class.h => include/configuration/tag_value.h   |  34 +-
 include/database/Export2DB.h                       | 153 ++++
 include/database/table_management.h                | 161 ++++
 {src => include/osm_elements}/Node.h               |  11 +-
 include/osm_elements/OSMDocument.h                 | 159 ++++
 {src => include/osm_elements}/Relation.h           |   3 +
 {src => include/osm_elements}/Way.h                |  17 +-
 {src => include/osm_elements}/osm_element.h        |  15 +-
 {src => include/osm_elements}/osm_tag.h            |   0
 .../parser}/ConfigurationParserCallback.h          |   4 +-
 .../parser}/OSMDocumentParserCallback.h            |   3 +-
 {src => include/parser}/XMLParser.h                |   0
 include/utilities/handle_pgpass.h                  |  29 +
 {src => include/utilities}/print_progress.h        |   2 +-
 {src => include/utilities}/prog_options.h          |   0
 include/utilities/utilities.h                      |  30 +
 mapconfig.xml                                      |  88 +-
 mapconfig_for_bicycles.xml                         | 116 +--
 mapconfig_for_cars.xml                             |  38 +-
 mapconfig_for_pedestrian.xml                       |  23 +
 src/Class.cpp                                      |  57 --
 src/Configuration.h                                |  76 --
 src/Export2DB.cpp                                  | 944 ---------------------
 src/Export2DB.h                                    | 160 ----
 src/OSMDocument.cpp                                | 136 ---
 src/OSMDocument.h                                  | 100 ---
 src/configuration/configuration.cpp                |  93 ++
 src/{Type.cpp => configuration/tag_key.cpp}        |  72 +-
 .../tag_value.cpp}                                 |  49 +-
 src/database/Export2DB.cpp                         | 700 +++++++++++++++
 src/database/configuration_config.cpp              |  81 ++
 src/database/osm_nodes_config.cpp                  |  82 ++
 src/database/osm_relations_config.cpp              |  83 ++
 src/database/osm_ways_config.cpp                   |  88 ++
 src/database/pois_config.cpp                       |  89 ++
 src/database/table_management.cpp                  | 444 ++++++++++
 src/database/ways_config.cpp                       | 130 +++
 src/database/ways_vertices_pgr_config.cpp          |  79 ++
 src/osm_element.cpp                                | 105 ---
 src/{ => osm_elements}/Node.cpp                    |  23 +-
 src/osm_elements/OSMDocument.cpp                   | 267 ++++++
 src/{ => osm_elements}/Relation.cpp                |  17 +-
 src/{ => osm_elements}/Way.cpp                     |  64 +-
 src/{ => osm_elements}/osm2pgrouting.cpp           | 158 +++-
 src/osm_elements/osm_element.cpp                   | 233 +++++
 src/{ => osm_elements}/osm_tag.cpp                 |   2 +-
 src/{ => parser}/ConfigurationParserCallback.cpp   |  25 +-
 src/{ => parser}/OSMDocumentParserCallback.cpp     |  70 +-
 src/{ => parser}/XMLParser.cpp                     |   3 +-
 src/utilities/handle_pgpass.cpp                    |  94 ++
 src/{ => utilities}/prog_options.cpp               |  26 +-
 src/utilities/utilities.cpp                        |  47 +
 tools/data/getdata.sh                              |   2 +
 tools/doxygen/Doxyfile                             |  12 +-
 tools/doxygen/images/pgrouting-logo.png            | Bin 0 -> 19294 bytes
 66 files changed, 3851 insertions(+), 1967 deletions(-)

diff --git a/.gitignore b/.gitignore
index b749c06..001d9f8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@ Sample/*
 build
 osm2pgrouting
 tools/vagrant/packaging.sh
+fix_typos
 *.o
 *.out
 *.osm
diff --git a/.travis.yml b/.travis.yml
index a64d480..c129de1 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -22,42 +22,31 @@ compiler:
 #  email:
 #    on_failure: project at pgrouting.org
 
-env: POSTGRESQL_VERSION=9.6   PG_USER=postgres
+env: POSTGRESQL_VERSION=9.6   PG_USER=postgres DIST=precise
       
 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
+      env: POSTGRESQL_VERSION=9.6   PG_USER=postgres DIST=trusty
 
 
     - os: linux
       sudo: required
       dist: trusty
       group: edge
-      env: POSTGRESQL_VERSION=9.5   PG_USER=postgres
+      env: POSTGRESQL_VERSION=9.5   PG_USER=postgres DIST=trusty
 
 
     - os: linux
       sudo: required
       dist: trusty
       group: edge
-      env: POSTGRESQL_VERSION=9.4   PG_USER=postgres
+      env: POSTGRESQL_VERSION=9.4   PG_USER=postgres DIST=trusty
 
 
 
@@ -80,7 +69,8 @@ before_install:
   - sudo sudo apt-get install -y libboost-program-options-dev
 
 install:
-  - sudo ./ci/travis/install-postgres.sh $POSTGRESQL_VERSION $PG_USER
+  #- sudo ./ci/travis/install-postgres.sh $POSTGRESQL_VERSION $PG_USER
+  - sudo ./ci/travis/install-libpqxx.sh $DIST
 
 before_script:
 
diff --git a/AUTHORS.md b/AUTHORS.md
index 5edfb79..050ba7e 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -9,6 +9,7 @@
 
 ## Other contributors:
 
+* Aakash Sharma
 * Adrien Pavie
 * Anton Patrushev
 * Daniel Wendt (Initial author) 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0f5fcfd..de75fb8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,6 +5,7 @@ set (CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
 set (SHARE_DIR "/usr/share/osm2pgrouting")
 
 FIND_PACKAGE(PostgreSQL REQUIRED)
+find_package(LibPQXX REQUIRED)
 FIND_PACKAGE(EXPAT REQUIRED)
 
 FIND_PACKAGE(Boost)
@@ -16,35 +17,53 @@ endif(Boost_INCLUDE_DIRS)
 
 FIND_PACKAGE(Boost COMPONENTS program_options REQUIRED)
 
-FILE(GLOB SRC "${CMAKE_SOURCE_DIR}/src/*.cpp" "${CMAKE_SOURCE_DIR}/src/*.h")
+FILE(GLOB osm2pgrouting_lib_SOURCES "${CMAKE_SOURCE_DIR}/src/*/*.cpp")
 
 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")
-
+set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Wconversion -pedantic -Wextra  -frounding-math -Wno-deprecated -fmax-errors=10")
 
 
+set (OSM2PGROUTING_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/include")
+message(STATUS "LIBPQXX_INCLUDE_DIRS: ${LIBPQXX_INCLUDE_DIRS}")
 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 "POSTGRESQL_LIBRARIES: ${POSTGRESQL_LIBRARIES}")
 message(STATUS "Boost_LIBRARIES: ${boost_LIBRARIES}")
+message(STATUS "LIBPQXX_LIBRARIES: ${LIBPQXX_LIBRARIES}")
+
+INCLUDE_DIRECTORIES(src
+    ${LIBPQXX_INCLUDE_DIRS}
+    ${POSTGRESQL_INCLUDE_DIR}
+    ${EXPAT_INCLUDE_DIRS}
+    ${Boost_INCLUDE_DIRS}
+    ${OSM2PGROUTING_INCLUDE_DIRS}
+    )
 
-INCLUDE_DIRECTORIES(src ${POSTGRESQL_INCLUDE_DIR} ${EXPAT_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
-
-ADD_EXECUTABLE(osm2pgrouting ${SRC})
+ADD_EXECUTABLE(osm2pgrouting ${osm2pgrouting_lib_SOURCES})
 
-TARGET_LINK_LIBRARIES(osm2pgrouting ${POSTGRESQL_LIBRARIES} ${EXPAT_LIBRARIES} ${Boost_LIBRARIES} )
+TARGET_LINK_LIBRARIES(osm2pgrouting
+    ${LIBPQXX_LIBRARIES}
+    ${POSTGRESQL_LIBRARIES}
+    ${EXPAT_LIBRARIES}
+    ${Boost_LIBRARIES}
+    )
 
 INSTALL(TARGETS osm2pgrouting
     RUNTIME DESTINATION "/usr/bin"
     )
 
+if(WIN32)
+    target_link_libraries(osm2pgrouting wsock32 ws2_32)
+endif()
+
 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"
+    "${CMAKE_SOURCE_DIR}/mapconfig_for_pedestrian.xml"
     DESTINATION "${SHARE_DIR}")
 
 
diff --git a/NEWS b/NEWS
index 56072f4..6e10eb7 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,12 @@
+osm2pgRouting 2.3.0
+
+* Cost should not return the same value
+* Added a points of Interest table
+* Some default one_way values are taken into consideration
+* Relations are also condsidered
+* New mapconfig_for_pedestrian.xml
+
+
 osm2pgRouting 2.2.0
 
 * Adding foreign keys to the tables.
diff --git a/Readme.md b/Readme.md
index 5d7befd..41bebd6 100644
--- a/Readme.md
+++ b/Readme.md
@@ -11,6 +11,7 @@ Before you can use this tool for importing Openstreetmap data you need to instal
 3. pgrouting
 4. boost
 5. expat
+5. libpqxx
 6. cmake
 
 and to prepare a database.
@@ -38,6 +39,9 @@ Install some prerqeuisites
 ```
 sudo apt-get install expat
 sudo apt-get install libexpat1-dev
+sudo apt-get install libboost-dev
+sudo apt-get install libboost-program-options-dev
+sudo apt install libpqxx-dev
 ```
 
 CMAKE options:
@@ -82,9 +86,7 @@ osm2pgrouting --f next-OSM-XML-File.osm --conf mapconfig.xml --dbname routing --
 A complete list of arguments are:
 
 ```
-Allowed options:
-
-
+ osm2pgrouting --help
 Allowed options:
 
 Help:
@@ -103,15 +105,22 @@ General:
                                         table names.
   --suffix arg                          Suffix added at the end of the table 
                                         names.
-  --addnodes                            Import the osm_nodes table.
+  --postgis                             Install postgis if not found.
+  --addnodes                            Import the osm_nodes, osm_ways &
+                                        osm_relations tables.
+  --attributes                          Include attributes information.
+  --tags                                Include tag information.
+  --chunk arg (=20000)                  Exporting chunk size.
   --clean                               Drop previously created tables.
+  --no-index                            Do not create indexes (Use when indexes
+                                        are already created)
 
 Database options:
-  -d [ --dbname ] arg               Name of your database (Required).
-  -U [ --username ] arg (=postgres) Name of the user, which have write access 
-                                    to the database.
-  -h [ --host ] arg (=localhost)    Host of your postgresql database.
-  -p [ --port ] arg (=5432)         db_port of your database.
-  -W [ --password ] arg             Password for database access.
+  -d [ --dbname ] arg            Name of your database (Required).
+  -U [ --username ] arg          Name of the user, which have write access to
+                                 the database.
+  -h [ --host ] arg (=localhost) Host of your postgresql database.
+  -p [ --port ] arg (=5432)      db_port of your database.
+  -W [ --password ] arg          Password for database access.
 
 ```
diff --git a/ci/travis/install-libpqxx.sh b/ci/travis/install-libpqxx.sh
new file mode 100755
index 0000000..33ad002
--- /dev/null
+++ b/ci/travis/install-libpqxx.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# ------------------------------------------------------------------------------
+# Travis CI scripts 
+# Copyright(c) pgRouting Contributors
+#
+# Install osm2pgrouting prerequesits
+# ------------------------------------------------------------------------------
+
+set -e
+
+
+DISTRIBUTION="$1"
+
+if [[ -z "$DISTRIBUTION=" ]] ; then
+    exit 1
+fi
+
+
+if [[ "$DISTRIBUTION" = "precise" ]] ; then
+    sudo apt-get install -y libpqxx3-dev
+elif [[ "$DISTRIBUTION" = "trusty" ]] ; then
+    sudo sudo sudo apt-get install -y libpqxx-dev
+else 
+    exit 1
+fi
+
diff --git a/ci/travis/osm2pgrouting_build.sh b/ci/travis/osm2pgrouting_build.sh
index 059181b..997b097 100755
--- a/ci/travis/osm2pgrouting_build.sh
+++ b/ci/travis/osm2pgrouting_build.sh
@@ -9,8 +9,10 @@
 # exit script on error
 set -e 
 
-# build pgRouting
-cmake  -DPOSTGRESQL_VERSION=$POSTGRESQL_VERSION
+# build osm2pgrouting
+mkdir build
+cd build
+cmake .. 
 make
 sudo make install
-
+cd ..
diff --git a/cmake/FindLibPQXX.cmake b/cmake/FindLibPQXX.cmake
new file mode 100644
index 0000000..eec3360
--- /dev/null
+++ b/cmake/FindLibPQXX.cmake
@@ -0,0 +1,43 @@
+# - Find libpqxx
+#   Find the libpqxx includes and client library
+# This module defines
+#  PQXX_INCLUDE_DIRS
+#  PQXX_LIBRARIES
+#  PQXX_FOUND
+
+include (FindPackageHandleStandardArgs)
+
+#
+# Look for an installation.
+#
+find_path(LIBPQXX_INCLUDE_DIR NAMES /include/pqxx/connection.hxx PATH_SUFFIXES ${SUFFIX_FOR_INCLUDE_PATH} PATHS
+
+    # Look in other places.
+    ${LIBPQXX_DIR_SEARCH}
+
+    # Help the user find it if we cannot.
+    DOC "The ${LIBPQXX_INCLUDE_DIR_MESSAGE}"
+    )
+
+# Now try to get the include and library path.
+if(LIBPQXX_INCLUDE_DIR)
+
+    if(EXISTS "${LIBPQXX_INCLUDE_DIR}")
+        set(LIBPQXX_INCLUDE_DIRS
+            ${LIBPQXX_INCLUDE_DIR}/include
+            )
+    endif()
+endif()
+
+find_library (LIBPQXX_LIBRARIES
+    NAMES
+    pqxx
+    )
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS("PQXX"
+    "libpqxx couldn't be found"
+    LIBPQXX_LIBRARIES
+    LIBPQXX_INCLUDE_DIRS
+    )
+
+mark_as_advanced (PQXX_INCLUDE_DIR PQXX_LIBRARY)
diff --git a/include/configuration/configuration.h b/include/configuration/configuration.h
new file mode 100644
index 0000000..18fb043
--- /dev/null
+++ b/include/configuration/configuration.h
@@ -0,0 +1,99 @@
+/***************************************************************************
+ *   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_CONFIGURATION_H_
+#define SRC_CONFIGURATION_H_
+
+#include <string>
+#include <map>
+#include <boost/lexical_cast.hpp>
+#include "configuration/tag_key.h"
+#include "configuration/tag_value.h"
+#include "osm_elements/osm_tag.h"
+
+namespace osm2pgr {
+class Configuration {
+ public:
+     Configuration() = default;
+
+     /** @brief add group of tag_key + all the tag_values
+      *
+      * @param[in] t_key Tag_key found in the configuration
+      */
+     void add_tag_key(const Tag_key &t_key);
+
+     /** @brief retrieves the Tag_value (attrributes
+      *
+      * @param[in] tag Tag found in the configuration
+      * @returns Tag_value
+      */
+     const Tag_value& tag_value(const Tag &tag) const;
+
+     /* Is the (key, value) pair in the configuration?
+      *
+      *
+      * @param[in] tag Tag (key, value) pair
+      */
+     bool has_tag(const Tag &tag) const;
+
+     /** retrieves the maxspeed based on the tag
+      * 
+      * if the (key,value) has a value this is returned
+      * else if the (key, *) has a value this is returned
+      * else 50  is returned
+      */
+
+     double maxspeed(const Tag &tag) const;
+     double maxspeed_forward(const Tag &tag) const;
+     double maxspeed_backward(const Tag &tag) const;
+
+     /** retrieves the priority based on the tag
+      * 
+      * if the (key,value) has a value this is returned
+      * else if the (key, *) has a value this is returned
+      * else 0  is returned
+      */
+
+     double priority(const Tag &tag) const;
+
+     /*
+      * data to be exported to configuration TABLE
+      */
+     const std::map<std::string, Tag_key>& types() const {return m_Tag_keys;}
+
+ private:
+     /** @brief is the tag key in the configuration file
+      * 
+      * @param[in] key  tag_key name="key"
+      */
+
+     bool has_tag_key(const std::string &key) const;
+     const Tag_key& tag_key(const Tag &tag) const;
+
+
+ private:
+     std::map<std::string, Tag_key> m_Tag_keys;
+};
+
+
+}  // end namespace osm2pgr
+#endif  // SRC_CONFIGURATION_H_
+
+
+
diff --git a/src/Type.h b/include/configuration/tag_key.h
similarity index 67%
rename from src/Type.h
rename to include/configuration/tag_key.h
index 174f101..35f2a4d 100644
--- a/src/Type.h
+++ b/include/configuration/tag_key.h
@@ -24,45 +24,39 @@
 
 #include <map>
 #include <cstdint>
+#include <cassert>
 #include <string>
-#include "./Class.h"
+#include "./tag_value.h"
 
 namespace osm2pgr {
 
-class Type {
+class Tag_key : Element {
  public:
-    Type() = default;
-    Type(const Type &) = default;
-    /**
+    Tag_key() = default;
+    Tag_key(const Tag_key &) = default;
+    /** @brief build it
      *    @param atts attributes read py the parser
      */
-    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;
-    }
+    explicit Tag_key(const char **atts);
+    void add_tag_value(const Tag_value &p_values);
 
-    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(const Class &pClass);
+    /* to have or not to have */
+    bool has(const Tag &tag, const std::string &str) const;
+    bool has_tag_value(const Tag &tag) const;
+
+    /* get it*/
+    std::string get(const Tag &tag, const std::string &str) const;
+    const Tag_value& tag_value(const Tag &tag) const;
+    inline int64_t id() const {return osm_id();}
+    inline std::string name() const {return get_attribute("name");}
+
+    /* used in the export function */
+    std::vector<std::string> values(
+            const std::vector<std::string> &columns) const;
 
  private:
-    std::map<std::string, Class> m_Classes;
-    int64_t m_id;
-    std::string m_name;
-    std::map<std::string, std::string> m_tags;
+    std::map<std::string, Tag_value> m_Tag_values;
 };
 
 }  // namespace osm2pgr
diff --git a/src/Class.h b/include/configuration/tag_value.h
similarity index 76%
rename from src/Class.h
rename to include/configuration/tag_value.h
index 23e3c54..615bc4f 100644
--- a/src/Class.h
+++ b/include/configuration/tag_value.h
@@ -21,29 +21,29 @@
 #ifndef SRC_CLASS_H_
 #define SRC_CLASS_H_
 
+#include <boost/lexical_cast.hpp>
+#include <osm_elements/osm_element.h>
+#include <cassert>
 #include <map>
 #include <string>
+#include <vector>
 
 namespace osm2pgr {
 
-class Class {
+class Tag_value : public Element {
  public:
-     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;
+     Tag_value() = default;
+     Tag_value(const Tag_value &) = default;
+     /** @brief build it */
+     explicit Tag_value(const char ** attributes);
+
+
+     /** @brief get it */
+     inline int64_t id() const {return osm_id();}
+     std::string name() const;
+     std::string get(const std::string &str) const;
+     std::vector<std::string> export_values() const; 
+
 };
 
 
diff --git a/include/database/Export2DB.h b/include/database/Export2DB.h
new file mode 100644
index 0000000..c83cdad
--- /dev/null
+++ b/include/database/Export2DB.h
@@ -0,0 +1,153 @@
+/***************************************************************************
+ *   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_EXPORT2DB_H_
+#define SRC_EXPORT2DB_H_
+
+#include <pqxx/pqxx>
+#include <libpq-fe.h>
+#include <map>
+#include <vector>
+#include <string>
+
+#include "osm_elements/Node.h"
+#include "osm_elements/Way.h"
+#include "osm_elements/Relation.h"
+#include "configuration/configuration.h"
+#include "utilities/prog_options.h"
+#include "database/table_management.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:
+     typedef std::vector<Node> Nodes;
+     typedef std::vector<Way> Ways;
+     typedef std::vector<Relation> Relations;
+
+     /**
+      * Constructor 
+      * @param vm variable map holding the configuration
+      * @param db_conn conection string 
+      *
+      */
+     explicit Export2DB(const po::variables_map &vm, const std::string &db_conn);
+
+     /**
+      * Destructor
+      * closes the connection to the database
+      */
+     ~Export2DB();
+
+#if 1
+     //! connects to database
+     int connect();
+#endif
+
+     bool has_extension(const std::string &name) const;
+#ifndef NDBEUG
+     bool install_postGIS() const;
+#endif
+
+     //! creates needed tables and geometries
+     void createTables() const;
+
+
+     /** @brief export values to osm_* table
+      *
+      * T must have:
+      *     T.values
+      *
+      * @param[in] items  vector of values to be inserted into
+      * @param[in] table 
+      */
+     template <typename T>
+         void export_osm (
+                 std::vector<T> &items,
+                 const std::string &table) const {
+             auto osm_table = m_tables.get_table(table);
+             std::vector<std::string> values(items.size(), "");
+
+             size_t i(0);
+             for (auto it = items.begin(); it != items.end(); ++it, ++i) {
+                 auto item = *it;
+                 values[i] = tab_separated(item.values(osm_table.columns(), true));
+             }
+
+             export_osm(values, osm_table);
+         }
+
+     void export_configuration(
+             const std::map<std::string, Tag_key>& items) const;
+
+     void exportWays(
+             const Ways &ways,
+             const Configuration &config) const;
+
+     void dropTables() const;
+     void createFKeys() const;
+     void process_pois() const;
+
+ private:
+
+     void export_osm(
+             const std::vector<std::string> &values,
+             const Table &table) const;
+
+     void process_section(const std::string &ways_columns, pqxx::work &Xaction) const;
+
+     void fill_vertices_table(
+             const std::string &table,
+             const std::string &vertices_tab,
+             pqxx::work &Xaction) const;
+
+     void fill_source_target(
+             const std::string &table,
+             const std::string &vertices_tab,
+             pqxx::work &Xaction) const;
+
+     int64_t get_val(const std::string sql) const;
+     void execute(const std::string sql) const;
+
+     Table configuration() const {return m_tables.configuration();}
+     Table vertices() const {return m_tables.vertices();}
+     Table ways() const {return m_tables.ways();}
+     Table pois() const {return m_tables.pois();}
+     Table osm_ways() const {return m_tables.osm_ways();}
+     Table osm_nodes() const {return m_tables.osm_nodes();}
+     Table osm_relations() const {return m_tables.osm_relations();}
+
+ private:
+     po::variables_map m_vm;
+
+     std::string conninf;
+
+     Tables m_tables;
+
+};
+}  // namespace osm2pgr
+
+#endif  // SRC_EXPORT2DB_H_
diff --git a/include/database/table_management.h b/include/database/table_management.h
new file mode 100644
index 0000000..18f06af
--- /dev/null
+++ b/include/database/table_management.h
@@ -0,0 +1,161 @@
+/*PGR-GNU*****************************************************************
+
+ Copyright (c) 2017 pgRouting developers
+ Mail: 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 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.
+********************************************************************PGR-GNU*/
+
+/** @file **/
+#pragma once
+#include <string>
+#include "utilities/prog_options.h"
+
+namespace osm2pgr {
+
+class Table {
+ public:
+     Table() = default;
+     Table(const Table &) = default;
+     Table(
+             const std::string &schema,
+             const std::string &name,
+             const std::string &full_name,
+
+             const std::string &create_str,
+             const std::string &other_columns,
+             const std::string &geometry
+          );
+
+     void set_columns(const std::vector<std::string> &columns);
+
+     /** @brief prefixNameSufix */
+     inline std::string table_name() const {
+         return m_full_name;
+     }
+
+
+     /** @brief schema.prefixNameSufix
+      *
+      * schema.prefixNameSufix
+      * OR
+      * prefixNameSufix
+      *
+      */
+     std::string addSchema() const;
+     std::string temp_name() const;
+     std::string name() const {return m_name;};
+     std::string full_name() const {return m_full_name;};
+
+     /** sql queries
+      */
+     std::string primary_key(const std::string &column) const;
+     std::string unique(const std::string &column) const;
+     std::string foreign_key(
+             const std::string &column,
+             const Table &table,
+             const std::string &table_column) const;
+     std::string gist_index() const;
+
+     inline std::vector<std::string> columns() const {
+         return m_columns;
+     }
+     std::string sql(int i) const {return m_sql[i];}
+
+
+     std::string tmp_create() const;
+     std::string create() const;
+     std::string drop() const;
+
+     /* modifier */
+     void add_sql(const string& sql) {
+         m_sql.push_back(sql);
+     }
+
+ private:
+     std::string m_name;
+     std::string m_schema;
+     std::string m_full_name;
+
+     std::string m_create;
+     std::string m_other_columns;
+     std::string m_constraint;
+     std::string m_geometry;
+     std::vector<std::string> m_columns;
+
+     /** aditional sqls (for pois) to keep code clean*/
+     std::vector<std::string> m_sql;
+};
+
+
+
+
+class Tables {
+    public:
+        Tables(const po::variables_map &vm);
+
+        const Table& get_table(const std::string &name) const {
+            if (name == "osm_nodes") return osm_nodes();
+            else if (name == "osm_ways") return osm_ways();
+            else if (name == "osm_relations") return osm_relations();
+            else if (name == "configuration") return configuration();
+            else if (name == "pointsofinterest") return pois();
+            else if (name == "ways") return ways();
+            else return vertices();
+        }
+
+        std::string  post_process(const Table &table) const;
+
+
+
+        po::variables_map m_vm;
+
+    private:
+        /*
+         * Conpulsory tables
+         */
+        Table m_ways;
+        Table m_ways_vertices_pgr;
+        Table m_points_of_interest;
+        Table m_configuration;
+
+        /*
+         * Optional tables
+         */
+        Table m_osm_nodes;
+        Table m_osm_ways;
+        Table m_osm_relations;
+
+    public:
+        const Table& ways() const {return m_ways;}
+        const Table& vertices() const {return m_ways_vertices_pgr;}
+        const Table& pois() const {return m_points_of_interest;}
+        const Table& configuration() const {return m_configuration;}
+        const Table& osm_nodes() const {return m_osm_nodes;}
+        const Table& osm_ways() const {return m_osm_ways;}
+        const Table& osm_relations() const {return m_osm_relations;}
+
+    private:
+        Table osm_nodes_config() const;
+        Table pois_config() const;
+        Table osm_ways_config() const;
+        Table osm_relations_config() const;
+        Table configuration_config() const;
+        Table ways_config() const;
+        Table ways_vertices_pgr_config() const;
+};
+
+}
+
+
diff --git a/src/Node.h b/include/osm_elements/Node.h
similarity index 92%
rename from src/Node.h
rename to include/osm_elements/Node.h
index 24e6aaa..281c17e 100644
--- a/src/Node.h
+++ b/include/osm_elements/Node.h
@@ -66,11 +66,18 @@ class Node : public Element {
       *    @param atts attributes read py the parser
       */
      explicit Node(const char **atts);
-     inline std::string geom_str(std::string separator) {
+     ~Node() {};
+
+     inline std::string geom_str(const std::string separator) const {
          return get_attribute("lon") + separator +  get_attribute("lat");
      }
+     inline std::string lat() {return get_attribute("lat");}
+     inline std::string lon() {return get_attribute("lon");}
+
+     void tag_config(const Tag &tag);
+
 
-     inline std::string point_geometry() {
+     std::string get_geometry() const {
          return
              std::string("srid=4326; POINT(")
              + geom_str(" ") + ")";
diff --git a/include/osm_elements/OSMDocument.h b/include/osm_elements/OSMDocument.h
new file mode 100644
index 0000000..62d4a2c
--- /dev/null
+++ b/include/osm_elements/OSMDocument.h
@@ -0,0 +1,159 @@
+/***************************************************************************
+ *   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_OSMDOCUMENT_H_
+#define SRC_OSMDOCUMENT_H_
+
+#include <iostream>
+#include <map>
+#include <vector>
+#include "utilities/utilities.h"
+#include "configuration/configuration.h"
+#include "utilities/prog_options.h"
+#include "database/Export2DB.h"
+
+namespace osm2pgr {
+
+
+class Node;
+class Way;
+class Relation;
+
+/**
+    An osm-document.
+*/
+class OSMDocument {
+ public:
+    typedef std::vector<Node> Nodes;
+    typedef std::vector<Way> Ways;
+    typedef std::vector<Relation> Relations;
+
+    //! Constructor
+    OSMDocument(
+            const Configuration& config,
+            const po::variables_map &vm,
+            const Export2DB &db_conn,
+            size_t lines);
+
+    inline size_t lines() const {return m_lines;}
+
+    //! Do the configuration has the @b tag ?
+    inline bool config_has_tag(const Tag &tag) const {
+        return m_rConfig.has_tag(tag);
+    }
+
+    inline double priority(const Tag &tag) const {
+        return m_rConfig.priority(tag);
+    }
+
+    inline double maxspeed(const Tag &tag) const {
+        return m_rConfig.maxspeed(tag);
+    }
+
+    const Nodes& nodes() const {return m_nodes;}
+    const Ways& ways() const {return m_ways;}
+    const Relations& relations() const {return m_relations;}
+
+    void AddNode(const Node &n);
+    void AddWay(const Way &w);
+    void AddRelation(const Relation &r);
+    void endOfFile() const;
+
+    //! find node by using an ID
+    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 add_node(Way &way, const char **atts);
+
+    /**
+     * add the configuration tag used for the speeds
+     */
+    void add_config(Element *osm_element, const Tag &tag) const;
+
+    inline uint16_t nodeErrs() const {return m_nodeErrs;}
+
+ private:
+    template <typename T>
+        bool
+        do_export_osm(const T &container) {
+            return m_vm.count("addnodes") && (container.size() % m_chunk_size) == 0;
+        }
+
+
+    void wait_child() const;
+
+    template <typename T>
+        void
+        osm_table_export(const T &osm_items, const std::string &table) const {
+            if (osm_items.empty()) return;
+
+            if (m_vm.count("addnodes")) {
+#if 0
+                auto pid = fork();
+                if (pid < 0) {
+                    std::cerr << "Failed to fork" << endl;
+                    exit(1);
+                }
+                if (pid > 0) return;
+#endif
+            }
+            auto residue = osm_items.size() % m_chunk_size;
+            size_t start = residue? osm_items.size() - residue : osm_items.size() - m_chunk_size;
+            auto export_items = T(osm_items.begin() + start, osm_items.end());
+
+            m_db_conn.export_osm(export_items, table);
+
+            if (m_vm.count("addnodes")) {
+#if 0
+                /*
+                 * finish the child process
+                 */
+                _exit(0);
+#endif
+            }
+        }
+
+   void export_pois() const;
+
+
+ private:
+    // ! parsed nodes TODO change to sorted vector
+    Nodes m_nodes;
+    //! parsed ways
+    Ways m_ways;
+    //! parsed relations
+    Relations  m_relations;
+
+    const Configuration& m_rConfig;
+    po::variables_map m_vm;
+    const Export2DB &m_db_conn;
+
+    size_t m_chunk_size;
+    uint16_t m_nodeErrs;
+    size_t m_lines;
+};
+
+}  // end namespace osm2pgr
+#endif  // SRC_OSMDOCUMENT_H_
diff --git a/src/Relation.h b/include/osm_elements/Relation.h
similarity index 96%
rename from src/Relation.h
rename to include/osm_elements/Relation.h
index 7e50286..e73bdf5 100644
--- a/src/Relation.h
+++ b/include/osm_elements/Relation.h
@@ -58,15 +58,18 @@ class Relation : public Element{
       */
      explicit Relation(const char ** atts);
      Relation() = delete;
+     ~Relation() {};
      Relation(const Relation&) = default;
      std::vector<int64_t> way_refs() const {return m_WayRefs;}
      std::vector<int64_t>& way_refs() {return m_WayRefs;}
+     std::string get_geometry() const {return std::string("");}
 
      /**
       *    saves the nodes of the way  
       *    @param atts member attributes read py the parser
       */
      int64_t add_member(const char **atts);
+     std::string members_str() const;
 
  private:
      std::vector<int64_t> m_WayRefs;
diff --git a/src/Way.h b/include/osm_elements/Way.h
similarity index 90%
rename from src/Way.h
rename to include/osm_elements/Way.h
index 3ce8362..b5d4e11 100644
--- a/src/Way.h
+++ b/include/osm_elements/Way.h
@@ -54,6 +54,7 @@ namespace osm2pgr {
 class Way : public Element {
  public:
      Way() = default;
+     ~Way() {};
 
      /**
       *  @param atts attributes read py the parser
@@ -61,11 +62,14 @@ class Way : public Element {
      explicit Way(const char **atts);
      Tag add_tag(const Tag &tag);
      void add_node(Node* node);
+     void add_node(int64_t node_id);
 
      std::vector<Node*>& nodeRefs() {return m_NodeRefs;}
      const std::vector<Node*> nodeRefs() const {return m_NodeRefs;}
 
 
+     std::string members_str() const;
+
  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;}
@@ -81,17 +85,15 @@ class Way : public Element {
      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 get_geometry() 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));
+         return boost::lexical_cast<std::string>(m_maxspeed_forward);
      }
      inline std::string maxspeed_backward_str() const {
-         return boost::lexical_cast<std::string>(
-                 static_cast<int>(m_maxspeed_backward));
+         return boost::lexical_cast<std::string>(m_maxspeed_backward);
      }
 
 
@@ -120,11 +122,14 @@ class Way : public Element {
 
 
  private:
+     /** references to node that its on the file */
      std::vector<Node*> m_NodeRefs;
 
+     /** node identifiers found as part of the way */
+     std::vector<int64_t> m_node_ids;
+
      double m_maxspeed_forward;
      double m_maxspeed_backward;
-
      std::string m_oneWay;
 };
 
diff --git a/src/osm_element.h b/include/osm_elements/osm_element.h
similarity index 86%
rename from src/osm_element.h
rename to include/osm_elements/osm_element.h
index 7007a86..3b32a6c 100644
--- a/src/osm_element.h
+++ b/include/osm_elements/osm_element.h
@@ -24,6 +24,7 @@
 #pragma once
 
 #include <string>
+#include <vector>
 #include <map>
 #include "./osm_tag.h"
 
@@ -51,18 +52,22 @@ class Element {
       *    @param atts attributes pointer returned by the XML parser
       */
      explicit Element(const char **atts);
+     virtual ~Element() {};
+
      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;}
+     virtual void tag_config(const Tag &tag);
      inline Tag tag_config() const {return m_tag_config;}
+     bool is_tag_configured() const;
 
 
 
      std::string attributes_str() const;
      std::string tags_str() const;
 
+     virtual std::string get_geometry() const {return "";}
      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;}
@@ -73,11 +78,19 @@ class Element {
 
      bool has_tag(const std::string&) const;
      std::string get_tag(const std::string&) const;
+
+     bool has_tags() const {return !m_tags.empty();}
      std::map<std::string, std::string>& tags() {return m_tags;}
      const std::map<std::string, std::string> tags() const {return m_tags;}
 
+     std::vector<std::string> values(
+             const std::vector<std::string> &columns,
+             bool is_hstore) const;
+     virtual std::string members_str() const {return std::string();};
+
  protected:
      // ! OSM ID of the element
+     // or id of a configuraton
      int64_t m_osm_id;
      bool m_visible;
      Tag m_tag_config;
diff --git a/src/osm_tag.h b/include/osm_elements/osm_tag.h
similarity index 100%
rename from src/osm_tag.h
rename to include/osm_elements/osm_tag.h
diff --git a/src/ConfigurationParserCallback.h b/include/parser/ConfigurationParserCallback.h
similarity index 98%
rename from src/ConfigurationParserCallback.h
rename to include/parser/ConfigurationParserCallback.h
index 224963b..9eaf306 100644
--- a/src/ConfigurationParserCallback.h
+++ b/include/parser/ConfigurationParserCallback.h
@@ -36,7 +36,7 @@
 namespace osm2pgr {
 
 class Configuration;
-class Type;
+class Tag_key;
 
 /**
   Parser callback for configuration files
@@ -55,7 +55,7 @@ class ConfigurationParserCallback : public xml::XMLParserCallback {
     Configuration& m_config;
 
     //! current type, which will be parsed
-    Type *m_current;
+    Tag_key* m_current;
 
     virtual void StartElement(const char *name, const char** atts);
 
diff --git a/src/OSMDocumentParserCallback.h b/include/parser/OSMDocumentParserCallback.h
similarity index 97%
rename from src/OSMDocumentParserCallback.h
rename to include/parser/OSMDocumentParserCallback.h
index 5b434ac..45adc09 100644
--- a/src/OSMDocumentParserCallback.h
+++ b/include/parser/OSMDocumentParserCallback.h
@@ -59,8 +59,7 @@ class OSMDocumentParserCallback :
     /**
      *    Constructor
      */
-    explicit OSMDocumentParserCallback(OSMDocument& doc)
-    :
+    explicit OSMDocumentParserCallback(OSMDocument& doc) :
         m_rDocument(doc),
         m_pActRelation(0),
         last_node(nullptr),
diff --git a/src/XMLParser.h b/include/parser/XMLParser.h
similarity index 100%
rename from src/XMLParser.h
rename to include/parser/XMLParser.h
diff --git a/include/utilities/handle_pgpass.h b/include/utilities/handle_pgpass.h
new file mode 100644
index 0000000..cc661eb
--- /dev/null
+++ b/include/utilities/handle_pgpass.h
@@ -0,0 +1,29 @@
+/*PGR-GNU*****************************************************************
+
+ Copyright (c) 2017 pgRouting developers
+ Mail: 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 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.
+********************************************************************PGR-GNU*/
+
+/** @file **/
+
+#include <boost/program_options.hpp>
+#include <string>
+
+namespace po = boost::program_options;
+
+
+void
+handle_pgpass(po::variables_map &vm);
diff --git a/src/print_progress.h b/include/utilities/print_progress.h
similarity index 97%
rename from src/print_progress.h
rename to include/utilities/print_progress.h
index 709c0ff..ecf66ea 100644
--- a/src/print_progress.h
+++ b/include/utilities/print_progress.h
@@ -47,6 +47,6 @@ print_progress(T1 wantProgress, T2 currentProgress) {
     std::cout << "\r"
         << bar
         << " (" << static_cast<int>(100 * percent) << "%)"
-        << std::flush;
+        << " Total porcessed: " << currentProgress << std::flush;
 }
 #endif  // SRC_PRINT_PROGRESS_H_
diff --git a/src/prog_options.h b/include/utilities/prog_options.h
similarity index 100%
rename from src/prog_options.h
rename to include/utilities/prog_options.h
diff --git a/include/utilities/utilities.h b/include/utilities/utilities.h
new file mode 100644
index 0000000..f609a1b
--- /dev/null
+++ b/include/utilities/utilities.h
@@ -0,0 +1,30 @@
+/*PGR-GNU*****************************************************************
+
+ Copyright (c) 2017 pgRouting developers
+ Mail: 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 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.
+********************************************************************PGR-GNU*/
+
+/** @file **/
+
+
+#include <string>    
+#include <vector>    
+    
+    
+std::string 
+comma_separated(const std::vector<std::string> &columns);
+std::string 
+tab_separated(const std::vector<std::string> &columns);
diff --git a/mapconfig.xml b/mapconfig.xml
index 2ee4f9d..3e750e7 100644
--- a/mapconfig.xml
+++ b/mapconfig.xml
@@ -1,48 +1,48 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <configuration>
-  <type name="highway" id="1">
-    <class name="motorway" id="101" />
-    <class name="motorway_link" id="102" />
-    <class name="motorway_junction" id="103" />
-    <class name="trunk" id="104" />
-    <class name="trunk_link" id="105" />    
-    <class name="primary" id="106" />
-    <class name="primary_link" id="107" />    
-    <class name="secondary" id="108" />
-    <class name="secondary_link" id="124" />
-    <class name="tertiary" id="109" />
-    <class name="tertiary_link" id="125" />
-    <class name="residential" id="110" />
-    <class name="living_street" id="111" />
-    <class name="service" id="112" />
-    <class name="track" id="113" />
-    <class name="pedestrian" id="114" />
-    <class name="services" id="115" />
-    <class name="bus_guideway" id="116" />
-    <class name="path" id="117" />
-    <class name="cycleway" id="118" />
-    <class name="footway" id="119" />
-    <class name="bridleway" id="120" />
-    <class name="byway" id="121" />
-    <class name="steps" id="122" />
+  <tag_name name="highway" id="1">
+    <tag_value name="motorway" id="101" />
+    <tag_value name="motorway_link" id="102" />
+    <tag_value name="motorway_junction" id="103" />
+    <tag_value name="trunk" id="104" />
+    <tag_value name="trunk_link" id="105" />    
+    <tag_value name="primary" id="106" />
+    <tag_value name="primary_link" id="107" />    
+    <tag_value name="secondary" id="108" />
+    <tag_value name="secondary_link" id="124" />
+    <tag_value name="tertiary" id="109" />
+    <tag_value name="tertiary_link" id="125" />
+    <tag_value name="residential" id="110" />
+    <tag_value name="living_street" id="111" />
+    <tag_value name="service" id="112" />
+    <tag_value name="track" id="113" />
+    <tag_value name="pedestrian" id="114" />
+    <tag_value name="services" id="115" />
+    <tag_value name="bus_guideway" id="116" />
+    <tag_value name="path" id="117" />
+    <tag_value name="cycleway" id="118" />
+    <tag_value name="footway" id="119" />
+    <tag_value name="bridleway" id="120" />
+    <tag_value name="byway" id="121" />
+    <tag_value name="steps" id="122" />
         
-    <class name="unclassified" id="123" />
-    <class name="road" id="100" />
-  </type>
-  <type name="cycleway" id="2">
-    <class name="lane" id="201" />
-    <class name="track" id="202" />
-    <class name="opposite_lane" id="203" />
-    <class name="opposite" id="204" />
-  </type>  
-  <type name="tracktype" id="3">
-    <class name="grade1" id="301" />
-    <class name="grade2" id="302" />
-    <class name="grade3" id="303" />
-    <class name="grade4" id="304" />
-    <class name="grade5" id="305" />
-  </type>  
-  <type name="junction" id="4">
-    <class name="roundabout" id="401" />
-  </type>  
+    <tag_value name="unclassified" id="123" />
+    <tag_value name="road" id="100" />
+  </tag_name>
+  <tag_name name="cycleway" id="2">
+    <tag_value name="lane" id="201" />
+    <tag_value name="track" id="202" />
+    <tag_value name="opposite_lane" id="203" />
+    <tag_value name="opposite" id="204" />
+  </tag_name>  
+  <tag_name name="tracktype" id="3">
+    <tag_value name="grade1" id="301" />
+    <tag_value name="grade2" id="302" />
+    <tag_value name="grade3" id="303" />
+    <tag_value name="grade4" id="304" />
+    <tag_value name="grade5" id="305" />
+  </tag_name>  
+  <tag_name name="junction" id="4">
+    <tag_value name="roundabout" id="401" />
+  </tag_name>  
 </configuration>
diff --git a/mapconfig_for_bicycles.xml b/mapconfig_for_bicycles.xml
index 4a7b7f5..eea8526 100644
--- a/mapconfig_for_bicycles.xml
+++ b/mapconfig_for_bicycles.xml
@@ -1,60 +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
+  <tag_name name="cycleway" id="1">
+    <tag_value name="track" priority="1.0" id="101" />
+    <tag_value name="lane" priority="1.5" id="102" />
+    <tag_value name="opposite_lane" priority="1.5" id="103" />
+    <tag_value name="opposite" priority="1.5" id="104" />
+    <tag_value name="shared_lane" priority="1.6" id="105" />
+    <tag_value name="shared" priority="1.6" id="106" />
+    <tag_value name="share_busway" priority="1.6" id="107" />
+  </tag_name>
+  <tag_name name="cycleway:right" id="2">
+    <tag_value name="track" priority="1.0" id="201" />
+    <tag_value name="lane" priority="1.5" id="202" />
+    <tag_value name="opposite_lane" priority="1.5" id="203" />
+    <tag_value name="opposite" priority="1.5" id="204" />
+    <tag_value name="shared_lane" priority="1.6" id="205" />
+    <tag_value name="shared" priority="1.6" id="206" />
+    <tag_value name="share_busway" priority="1.6" id="207" />
+  </tag_name>
+  <tag_name name="cycleway:left" id="3">
+    <tag_value name="track" priority="1.0" id="301" />
+    <tag_value name="lane" priority="1.5" id="302" />
+    <tag_value name="opposite_lane" priority="1.5" id="303" />
+    <tag_value name="opposite" priority="1.5" id="304" />
+    <tag_value name="shared_lane" priority="1.6" id="305" />
+    <tag_value name="shared" priority="1.6" id="306" />
+    <tag_value name="share_busway" priority="1.6" id="307" />
+  </tag_name>
+  <tag_name name="tracktype" id="4">
+    <tag_value name="grade1" priority="1.0" id="401" />
+    <tag_value name="grade2" priority="1.1" id="402" />
+    <tag_value name="grade3" priority="1.2" id="403" />
+    <tag_value name="grade4" priority="1.3" id="404" />
+    <tag_value name="grade5" priority="1.4" id="405" />
+  </tag_name>
+  <tag_name name="highway" id="5">
+    <tag_value name="cycleway" priority="1.0" id="501" />
+    <tag_value name="path" priority="1.1" id="502" />
+    <tag_value name="pedestrian" priority="1.1" id="503" />
+    <tag_value name="footway" priority="1.1" id="504" />
+    <tag_value name="bridleway" priority="1.3" id="505" />
+    <tag_value name="track" priority="1.0" id="506" />
+    <tag_value name="living_street" priority="2.0" id="507" />
+    <tag_value name="service" priority="2.0" id="508" />
+    <tag_value name="residential" priority="2.2" id="509" />
+    <tag_value name="unclassified" priority="2.3" id="510" />
+    <tag_value name="tertiary_link" priority="2.5" id="511" />
+    <tag_value name="tertiary" priority="2.5" id="512" />
+    <tag_value name="services" priority="2.7" id="513" />
+    <tag_value name="secondary_link" priority="3.0" id="514" />
+    <tag_value name="secondary" priority="3.0" id="515" />
+    <tag_value name="primary_link" priority="3.5" id="516" />
+    <tag_value name="primary" priority="3.5" id="517" />
+    <tag_value name="road" priority="4.0" id="500" />
+  </tag_name>
+  <tag_name name="junction" id="6">
+    <tag_value name="roundabout" priority="2.5" id="601" />
+  </tag_name>  
+</configuration>
diff --git a/mapconfig_for_cars.xml b/mapconfig_for_cars.xml
index d3084b0..899d479 100644
--- a/mapconfig_for_cars.xml
+++ b/mapconfig_for_cars.xml
@@ -1,20 +1,22 @@
 <?xml version="1.0" encoding="UTF-8"?>
-  <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" />
-    <class name="motorway_junction" id="103" priority="1.0" maxspeed="130" />
-    <class name="trunk" id="104"  priority="1.05" maxspeed="110" />
-    <class name="trunk_link" id="105"  priority="1.05" maxspeed="110" />    
-    <class name="primary" id="106"  priority="1.15" maxspeed="90" />
-    <class name="primary_link" id="107"  priority="1.15" maxspeed="90" />    
-    <class name="secondary" id="108"  priority="1.5" maxspeed="90" />
-    <class name="secondary_link" id="109"  priority="1.5" maxspeed="90"/>  
-    <class name="tertiary" id="110"  priority="1.75" maxspeed="90" />
-    <class name="tertiary_link" id="111"  priority="1.75" maxspeed="90" />  
-    <class name="residential" id="112"  priority="2.5" maxspeed="50" />
-    <class name="living_street" id="113"  priority="3" maxspeed="20" />
-    <class name="service" id="114"  priority="2.5" maxspeed="50" />
+<configuration>
+  <tag_name name="highway" id="1">
+    <tag_value name="motorway"          id="101" priority="1.0" maxspeed="130" />
+    <tag_value name="motorway_link"     id="102" priority="1.0" maxspeed="130" />
+    <tag_value name="motorway_junction" id="103" priority="1.0" maxspeed="130" />
+    <tag_value name="trunk"             id="104" priority="1.05" maxspeed="110" />
+    <tag_value name="trunk_link"        id="105" priority="1.05" maxspeed="110" />    
+    <tag_value name="primary"           id="106" priority="1.15" maxspeed="90" />
+    <tag_value name="primary_link"      id="107" priority="1.15" maxspeed="90" />    
+    <tag_value name="secondary"         id="108" priority="1.5" maxspeed="90" />
+    <tag_value name="secondary_link"    id="109" priority="1.5" maxspeed="90"/>  
+    <tag_value name="tertiary"          id="110" priority="1.75" maxspeed="90" />
+    <tag_value name="tertiary_link"     id="111" priority="1.75" maxspeed="90" />  
+    <tag_value name="residential"       id="112" priority="2.5" maxspeed="50" />
+    <tag_value name="living_street"     id="113" priority="3" maxspeed="20" />
+    <tag_value name="service"           id="114" priority="2.5" maxspeed="50" />
         
-    <class name="unclassified" id="117" priority="3" maxspeed="90"/>
-    <class name="road" id="100" priority="5" maxspeed="50" />
-  </type> 
+    <tag_value name="unclassified"      id="117" priority="3" maxspeed="90"/>
+    <tag_value name="road"              id="100" priority="5" maxspeed="50" />
+  </tag_name> 
+</configuration>
diff --git a/mapconfig_for_pedestrian.xml b/mapconfig_for_pedestrian.xml
new file mode 100644
index 0000000..dac326d
--- /dev/null
+++ b/mapconfig_for_pedestrian.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+
+  <tag_name name="highway" id="1">
+    <tag_value name="footway" id="115"  priority="2.5" maxspeed="5" />
+    <tag_value name="steps" id="116"  priority="2.5" maxspeed="5" />
+    <tag_value name="pedestrian" id="117"  priority="2.5" maxspeed="5" />
+
+    <tag_value name="unclassified" id="118" priority="3" maxspeed="9"/>
+    <tag_value name="road" id="119" priority="5" maxspeed="5" />
+    <tag_value name="path" id="120"  priority="2.5" maxspeed="5" />
+  </tag_name>
+
+
+
+  <tag_name name="barrier" id="3">
+    <tag_value name="kerb" id="301" priority="1.0" maxspeed="13" />
+    <tag_value name="gate" id="302" priority="1.0" maxspeed="13" />
+    <tag_value name="bollard" id="303" priority="1.0" maxspeed="13" />
+    <tag_value name="cycle_barrier" id="304" priority="1.0" maxspeed="13" />
+  </tag_name>
+
+</configuration>
diff --git a/src/Class.cpp b/src/Class.cpp
deleted file mode 100644
index 3e95f37..0000000
--- a/src/Class.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/***************************************************************************
- *   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(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/Configuration.h b/src/Configuration.h
deleted file mode 100644
index 721c954..0000000
--- a/src/Configuration.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/***************************************************************************
- *   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_CONFIGURATION_H_
-#define SRC_CONFIGURATION_H_
-
-#include <string>
-#include <map>
-#include "Type.h"
-#include "./osm_tag.h"
-#include "./Class.h"
-
-namespace osm2pgr {
-
-/**
-A configuration document.
-*/
-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;
-     }
-
- private:
-     //! Map, which saves the parsed types
-     std::map<std::string, Type> m_Types;
-};
-
-
-}  // end namespace osm2pgr
-#endif  // SRC_CONFIGURATION_H_
diff --git a/src/Export2DB.cpp b/src/Export2DB.cpp
deleted file mode 100644
index e2d6e99..0000000
--- a/src/Export2DB.cpp
+++ /dev/null
@@ -1,944 +0,0 @@
-/***************************************************************************
- *   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 "./Export2DB.h"
-
-#include <unistd.h>
-
-#include <iostream>
-#include <map>
-#include <string>
-#include <vector>
-
-#include "./print_progress.h"
-#include "boost/algorithm/string/replace.hpp"
-
-
-#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())
-            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 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.
-     ***/
-}
-
-
-/*!
-
-  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
-        + table_description + ")";
-
-
-    PGresult *result = PQexec(mycon, sql.c_str());
-    bool created = (PQresultStatus(result) == PGRES_COMMAND_OK);
-
-    PQclear(result);
-    return created;
-}
-
-/*!
-
-  CREATE TABLE table (
-  table_description,
-  constraint
-  );
-
-*/
-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) {
-        std::cout << PQresultErrorMessage(result) << "\n";
-        throw;
-    }
-    return  static_cast<bool>(PQntuples(result));
-}
-
-bool Export2DB::createTable(const std::string &table_description,
-        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";
-
-    PQclear(result);
-    return created;
-}
-
-
-void Export2DB::addGeometry(
-        const std::string &schema, const std::string &table,
-        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);";
-
-
-    PGresult *result = PQexec(mycon, sql.c_str());
-
-    if (PQresultStatus(result) != PGRES_TUPLES_OK) {
-        std::cout << PQresultErrorMessage(result) << "<-------\n";
-        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);";
-
-
-    PGresult *result = PQexec(mycon, sql.c_str());
-    if (PQresultStatus(result) != PGRES_TUPLES_OK) {
-        std::cout << PQresultErrorMessage(result);
-        throw std::string(PQresultErrorMessage(result));
-    }
-    PQclear(result);
-}
-
-
-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);");
-    PGresult *result = PQexec(mycon, sql.c_str());
-
-    if (PQresultStatus(result) != PGRES_COMMAND_OK) {
-        std::cout << 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 + ");");
-    PGresult *result = PQexec(mycon, sql.c_str());
-    // TODO(who) check missing
-    PQclear(result);
-}
-
-// /////////////////////
-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(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"));
-#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);
-    PGresult *result = PQexec(mycon, drop_tables.c_str());
-    PQclear(result);
-}
-
-
-
-void Export2DB::dropTables() const {
-    auto ways_name = full_table_name("ways");
-    auto vertices_name = ways_name + "_vertices_pgr";
-
-    dropTable(addSchema(ways_name));
-    dropTable(addSchema(vertices_name));
-
-    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**
- doesn't exist already
-
-*/
-void  Export2DB::prepareExportNodes(const std::string nodes_columns) const {
-    if (createTempTable(create_nodes, "__nodes_temp"))
-        addTempGeometry("__nodes_temp", "POINT");
-
-    std::string copy_nodes("COPY __nodes_temp (" + nodes_columns + ") FROM STDIN");
-    PGresult* q_result = PQexec(mycon, copy_nodes.c_str());
-    PQclear(q_result);
-}
-
-
-
-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;
-        }
-
-        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());
-    }
-
-    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); ");
-    PGresult* q_result = PQexec(mycon, insert_into_nodes.c_str());
-    PQclear(q_result);
-    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::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)");
-
-    PGresult* q_result = PQexec(mycon, sql.c_str());
-    std::cout << "Vertices inserted " << PQcmdTuples(q_result);
-    PQclear(q_result);
-}
-
-
-
-
-
-void Export2DB::fill_source_target(const std::string &table, const std::string &vertices_tab) const {
-    // 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;");
-    PGresult* q_result = PQexec(mycon, sql1.c_str());
-    //     std::cout << " Updated: " << PQcmdTuples(q_result) << " rows\n";
-    PQclear(q_result);
-
-    //     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;");
-    q_result = PQexec(mycon, sql2.c_str());
-    //     std::cout << " Updated: " << PQcmdTuples(q_result) << " rows\n";
-    PQclear(q_result);
-
-    //     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::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";
-    PQclear(q_result);
-}
-
-
-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 (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, 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());
-    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
-
-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, 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 (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());
-        }
-    }
-    PQputline(mycon, "\\.\n");
-    PQendcopy(mycon);
-    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))"
-
-            " INSERT INTO " + addSchema(full_table_name("relations_ways")) +
-            " SELECT * FROM data; ");
-    q_result = PQexec(mycon, insert_into_relations_ways.c_str());
-    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::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");
-    PGresult* q_result = PQexec(mycon, copy_way_tag.c_str());
-
-    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.osm_id());
-            row_data += "\n";
-            PQputline(mycon, row_data.c_str());
-        }
-    }
-    PQputline(mycon, "\\.\n");
-    PQendcopy(mycon);
-    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))"
-
-            " INSERT INTO " +  addSchema("osm_way_tags") +
-            " SELECT * FROM data; ");
-
-    q_result = PQexec(mycon, insert_into_tags.c_str());
-    std::cout << "\t Inserted: " << PQcmdTuples(q_result) << " in " << addSchema("osm_way_tags") << "\n";
-    PQclear(q_result);
-
-    dropTable("__way_tag_temp");
-}
-
-
-void Export2DB::prepare_table(const std::string &ways_columns) const {
-    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");
-
-    PGresult* q_result = PQexec(mycon, copy_ways.c_str());
-    PQclear(q_result);
-}
-
-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, "
-            " 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;
-    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);
-            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);
-        }
-
-        // 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", "");
-            name_data = escaped_name.substr(0, 199);
-        }
-
-        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);
-    std::cout << "    Ways Processed: " << count << "\t";
-    std::cout << "    Split Ways generated: " << split_count << "\t";
-    process_section(ways_columns);
-}
-
-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 << "Deleting  duplicated ways from temporary table\n";
-    std::string delete_from_temp(
-            " 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";
-    PQclear(q_result);
-
-    //  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(vertices_name));
-
-    //  std::cout << "Updating to new toplology the temporary table\n";
-    fill_source_target("__ways_temp" , addSchema(vertices_name));
-
-
-    //  std::cout << "Inserting new split ways to '" << addSchema(full_table_name("ways")) << "'\n";
-    std::string insert_into_ways(
-            " 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) << " split ways\n";
-    PQclear(q_result);
-    dropTable("__ways_temp");
-}
-
-
-
-
-
-
-
-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");
-
-    PGresult* q_result = PQexec(mycon, copy_types.c_str());
-
-    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 += "\n";
-        PQputline(mycon, row_data.c_str());
-    }
-    PQputline(mycon, "\\.\n");
-    PQendcopy(mycon);
-    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))"
-
-            " INSERT INTO "  + addSchema("osm_way_types") + " (type_id, name) "
-            " (SELECT *  FROM data); ");
-
-    q_result = PQexec(mycon, insert_into_types.c_str());
-    std::cout << "\t Inserted: " << PQcmdTuples(q_result) << " in " << addSchema("osm_way_types") << "\n";
-
-    PQclear(q_result);
-    dropTable("__way_types_temp");
-}
-
-
-
-
-
-
-void Export2DB::exportClasses(const std::map<std::string, Type> &types)  const {
-    std::cout << "    Processing way's classes: ";
-
-    std::string copy_classes(
-            "COPY __classes_temp"
-            "   (class_id, type_id, name, priority, default_maxspeed)"
-            "   FROM STDIN");
-
-    createTempTable(create_classes, "__classes_temp");
-    PGresult *q_result = PQexec(mycon, copy_classes.c_str());
-
-    for (auto it = types.begin(); it != types.end(); ++it) {
-        auto t = *it;
-        auto type(t.second);
-
-        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 += "\t";
-            row_data += clss.name();
-            row_data += "\t";
-            row_data += TO_STR(clss.priority());
-            row_data += "\t";
-            row_data += TO_STR(clss.default_maxspeed());
-            row_data += "\n";
-            PQputline(mycon, row_data.c_str());
-        }
-    }
-    PQputline(mycon, "\\.\n");
-    PQendcopy(mycon);
-    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))"
-
-            " INSERT INTO " + addSchema("osm_way_classes") +
-            " SELECT *  FROM data; ");
-
-    q_result = PQexec(mycon, insert_into_classes.c_str());
-    std::cout << "\t Inserted: " << PQcmdTuples(q_result) << " in " << addSchema("osm_way_classes") << "\n";
-
-    PQclear(q_result);
-    dropTable("__classes_temp");
-}
-
-
-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
deleted file mode 100644
index 8924542..0000000
--- a/src/Export2DB.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/***************************************************************************
- *   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_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:
-     /**
-      * 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:
-     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  // SRC_EXPORT2DB_H_
diff --git a/src/OSMDocument.cpp b/src/OSMDocument.cpp
deleted file mode 100644
index 0a62313..0000000
--- a/src/OSMDocument.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/***************************************************************************
- *   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 <vector>
-#include <map>
-#include <utility>
-#include <string>
-#include <iostream>
-#include "./OSMDocument.h"
-#include "./Configuration.h"
-#include "./Node.h"
-#include "./Relation.h"
-#include "./Way.h"
-
-namespace osm2pgr {
-
-OSMDocument::OSMDocument(const Configuration &config, size_t lines) :
-    m_nodesErrs(0),
-    m_rConfig(config),
-    m_lines(lines) {
-}
-
-
-void OSMDocument::AddNode(Node n) {
-    m_Nodes[n.osm_id()] = n;
-}
-
-void OSMDocument::AddWay(Way w) {
-    m_Ways[w.osm_id()] = w;
-}
-
-void OSMDocument::AddRelation(const Relation &r) {
-    m_Relations.push_back(r);
-}
-
-Node*
-OSMDocument::FindNode(int64_t nodeRefId) {
-    auto it = m_Nodes.find(nodeRefId);
-    return &(it->second);
-}
-
-bool
-OSMDocument::has_node(int64_t nodeRefId) const {
-    auto it = m_Nodes.find(nodeRefId);
-    return (it != m_Nodes.end());
-}
-
-Way*
-OSMDocument::FindWay(int64_t way_id) {
-    auto it = m_Ways.find(way_id);
-    return &(it->second);
-}
-
-bool
-OSMDocument::has_way(int64_t way_id) const {
-    auto it = m_Ways.find(way_id);
-    return (it != m_Ways.end());
-}
-
-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);
-    }
-}
-
-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);
-                }
-            }
-#endif
-        }
-    }
-}
-
-
-}  // namespace osm2pgr
diff --git a/src/OSMDocument.h b/src/OSMDocument.h
deleted file mode 100644
index 4e38b3f..0000000
--- a/src/OSMDocument.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/***************************************************************************
- *   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_OSMDOCUMENT_H_
-#define SRC_OSMDOCUMENT_H_
-
-#include <map>
-#include <vector>
-#include <string>
-#include "./Configuration.h"
-
-namespace osm2pgr {
-
-
-class Node;
-class Way;
-class Relation;
-
-/**
-    An osm-document.
-*/
-class OSMDocument {
- public:
-    //! 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);
-    }
-
-    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;}
-
-    //! add node to the map
-    void AddNode(Node n);
-
-    //! add way to the map
-    void AddWay(Way w);
-
-    //! find node by using an ID
-    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/configuration/configuration.cpp b/src/configuration/configuration.cpp
new file mode 100644
index 0000000..5019353
--- /dev/null
+++ b/src/configuration/configuration.cpp
@@ -0,0 +1,93 @@
+/***************************************************************************
+ *   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 "configuration/configuration.h"
+#include <boost/lexical_cast.hpp>
+#include <iostream>
+#include <string>
+
+namespace osm2pgr {
+
+void Configuration::add_tag_key(const Tag_key &t_key) {
+    if (has_tag_key(t_key.name())) {
+        std::cerr << "Duplicate Tag_key found in condfiguration file"
+            << t_key.name() << " ....  sikipping\n";
+        return;
+    }
+    m_Tag_keys[t_key.name()] = t_key;
+}
+
+
+bool 
+Configuration::has_tag_key(const std::string &key) const {
+        return m_Tag_keys.count(key) != 0; 
+}                      
+
+
+bool
+Configuration::has_tag(const Tag &tag) const {
+    return has_tag_key(tag.key())
+        && tag_key(tag).has_tag_value(tag);
+}
+
+
+const Tag_value& 
+Configuration::tag_value(const Tag &tag) const {
+    return tag_key(tag).tag_value(tag);
+}                      
+
+
+const Tag_key& 
+Configuration::tag_key(const Tag &tag) const {
+    return m_Tag_keys.at(tag.key()); 
+}                      
+
+
+double
+Configuration::maxspeed(const Tag &tag) const {
+    if (tag_key(tag).has(tag, "maxspeed"))
+        return boost::lexical_cast<double>(tag_key(tag).get(tag, "maxspeed"));
+    return 50;
+}
+
+double
+Configuration::maxspeed_forward(const Tag &tag) const {
+    if (tag_key(tag).has(tag, "maxspeed:backward"))
+        return boost::lexical_cast<double>(tag_key(tag).get(tag, "maxspeed:backward"));
+    return maxspeed(tag);
+}
+
+double
+Configuration::maxspeed_backward(const Tag &tag) const {
+    if (tag_key(tag).has(tag, "maxspeed:forward"))
+        return boost::lexical_cast<double>(tag_key(tag).get(tag, "maxspeed:backward"));
+    return maxspeed(tag);
+}
+
+double
+Configuration::priority(const Tag &tag) const {
+    if (tag_key(tag).has(tag, "priority"))
+        return boost::lexical_cast<double>(tag_key(tag).get(tag, "priority"));
+    return 0;
+}
+
+
+}  // end namespace osm2pgr
diff --git a/src/Type.cpp b/src/configuration/tag_key.cpp
similarity index 53%
rename from src/Type.cpp
rename to src/configuration/tag_key.cpp
index 3786144..240a399 100644
--- a/src/Type.cpp
+++ b/src/configuration/tag_key.cpp
@@ -18,39 +18,67 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
+#include "configuration/tag_key.h"
+#include "utilities/utilities.h"
 #include <boost/lexical_cast.hpp>
 #include <string>
 #include <map>
-#include "./Class.h"
-#include "./Type.h"
 
 namespace osm2pgr {
 
-void Type::AddClass(const Class &pClass) {
-    m_Classes[pClass.name()] = pClass;
+
+Tag_key::Tag_key(const char **atts) 
+    : Element(atts) {
 }
 
+void
+Tag_key::add_tag_value(const Tag_value &value) {
+    m_Tag_values[value.name()] =  value;
+}
 
-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;
-        }
-    }
+bool
+Tag_key::has_tag_value(const Tag &tag) const {
+    return m_Tag_values.count(tag.value());
 }
 
-void
-Type::add_class(const char **atts) {
-    AddClass(Class(atts));
+const
+Tag_value&
+Tag_key::tag_value(
+        const Tag &tag) const {
+    return m_Tag_values.at(tag.value());
+}
+
+bool
+Tag_key::has(const Tag &tag, const std::string &str) const {
+    return tag_value(tag).has_attribute(str)
+           || this->has_attribute(str);
+}
+
+std::string
+Tag_key::get(const Tag &tag, const std::string &str) const {
+    assert(this->has(tag, str));
+    return (tag_value(tag).has_attribute(str)) ?
+        tag_value(tag).get(str)
+        : this->get_attribute(str);
+}
+
+
+std::vector<std::string> 
+Tag_key::values(const std::vector<std::string> &columns) const {
+    std::vector<std::string> export_values;
+
+    for (const auto &item : m_Tag_values) {
+        auto row = item.second.values(columns, true);
+        row[1] = name();
+        row[2] = item.second.get_attribute("name"); 
+        // row[3] has priority
+        if (row[4] == "") row[4] = "40"; // max_speed
+        if (row[5] == "") row[5] = row[4]; 
+        if (row[6] == "") row[6] = row[4];
+        if (row[7] == "") row[7] = "N"; 
+        export_values.push_back(tab_separated(row));
+    }
+    return export_values;
 }
 
 
diff --git a/src/Configuration.cpp b/src/configuration/tag_value.cpp
similarity index 68%
rename from src/Configuration.cpp
rename to src/configuration/tag_value.cpp
index fd711bb..3dc94a2 100644
--- a/src/Configuration.cpp
+++ b/src/configuration/tag_value.cpp
@@ -18,41 +18,48 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
-
-#include "./Configuration.h"
+#include "configuration/tag_value.h"
 #include <boost/lexical_cast.hpp>
-#include <iostream>
 #include <string>
-#include "./osm_tag.h"
-#include "./Type.h"
-#include "./Class.h"
+#include <cassert>
+
 
 
 namespace osm2pgr {
 
 
-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;
+Tag_value::Tag_value(const char **atts) :
+    Element(atts){
+        assert(has_attribute("name"));
 }
 
-Type& Configuration::FindType(std::string name) {
-    return m_Types.at(name);
+std::string
+Tag_value::get(const std::string &str) const {
+    assert(has_attribute(str));
+    return  get_attribute(str);
 }
-Type Configuration::FindType(std::string name) const {
-    return m_Types.at(name);
+
+#if 0
+std::string
+Tag_value::priority() const {
+    assert(has_attribute("priority"));
+    return  get_attribute("priority");
 }
 
-Class Configuration::FindClass(const Tag &tag) const {
-    return m_Types.at(tag.key()).classes()[tag.value()];
+std::string
+Tag_value::maxspeed() const {
+    assert(has_attribute("maxspeed"));
+    return  get_attribute("maxspeed");
 }
+#endif
 
-std::string Configuration::priority_str(const Tag &tag) const {
-    return  boost::lexical_cast<std::string>(FindClass(tag).priority());
+std::string
+Tag_value::name() const {
+    assert(has_attribute("name"));
+    return get_attribute("name");
 }
 
+
+
+
 }  // end namespace osm2pgr
diff --git a/src/database/Export2DB.cpp b/src/database/Export2DB.cpp
new file mode 100644
index 0000000..6df5313
--- /dev/null
+++ b/src/database/Export2DB.cpp
@@ -0,0 +1,700 @@
+/***************************************************************************
+ *   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 "database/Export2DB.h"
+#include "database/table_management.h"
+
+#include <unistd.h>
+
+#include <iostream>
+#include <map>
+#include <string>
+#include <vector>
+
+#include "utilities/print_progress.h"
+#include "utilities/prog_options.h"
+#include "utilities/utilities.h"
+
+#include "boost/algorithm/string/replace.hpp"
+
+
+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, const std::string &connection) :
+    m_vm(vm),
+    conninf(connection),
+    m_tables(vm)
+{
+}
+
+Export2DB::~Export2DB() {
+#if 0
+    PQfinish(mycon);
+#endif
+}
+
+int Export2DB::connect() {
+    try {
+        pqxx::connection db_conn(conninf);
+        pqxx::work Xaction(db_conn);
+        cout << "connection success"<< endl;
+        return 0;
+
+    } catch (const std::exception &e) {
+        cerr << e.what() << std::endl;
+        return 1;
+    }
+}
+
+
+bool
+Export2DB::has_extension(const std::string &name) const {
+    try {
+        pqxx::connection db_conn(conninf);
+        pqxx::work Xaction(db_conn);
+        std::string sql = "SELECT * FROM pg_extension WHERE extname = '" + name + "'";
+        auto result = Xaction.exec(sql);
+        return result.size() == 1;
+
+    } catch (const std::exception &e) {
+        cerr << e.what() << std::endl;
+        return false;
+    }
+}
+
+
+#ifndef NDEBUG
+bool
+Export2DB::install_postGIS() const {
+    try {
+        pqxx::connection db_conn(conninf);
+        pqxx::work Xaction(db_conn);
+        Xaction.exec("CREATE EXTENSION postgis");
+        Xaction.exec("CREATE EXTENSION hstore");
+        Xaction.commit();
+        return true;
+    } catch (const std::exception &e) {
+        // cerr << e.what() << std::endl;
+    }
+    return false;
+}
+#endif
+
+
+
+
+// /////////////////////
+void Export2DB::createTables() const {
+    //  the following are particular of the file tables
+    try {
+        pqxx::connection db_conn(conninf);
+        pqxx::work Xaction(db_conn);
+
+        Xaction.exec(vertices().create());
+        std::cout << "TABLE: " << vertices().addSchema() << " created ... OK.\n";
+
+        Xaction.exec(ways().create());
+        std::cout << "TABLE: " << ways().addSchema() << " created ... OK.\n";
+
+        Xaction.exec(pois().create());
+        std::cout << "TABLE: " << pois().addSchema() << " created ... OK.\n";
+
+        Xaction.exec(configuration().create());
+        std::cout << "TABLE: " << configuration().addSchema() << " created ... OK.\n";
+
+        Xaction.commit();
+    } catch (const std::exception &e) {
+        std::cerr <<  "\n" << e.what() << std::endl;
+        std::cerr <<  "FATAL ERROR: could not routing tables" << std::endl;
+        exit(1);
+    }
+
+    try {
+        pqxx::connection db_conn(conninf);
+        pqxx::work Xaction(db_conn);
+        /*
+         * optional tables
+         */
+        Xaction.exec(osm_nodes().create());
+        std::cout << "TABLE: " << osm_nodes().addSchema() << " created ... OK.\n";
+
+        Xaction.exec(osm_ways().create());
+        std::cout << "TABLE: " << osm_ways().addSchema() << " created ... OK.\n";
+
+        Xaction.exec(osm_relations().create());
+        std::cout << "TABLE: " << osm_relations().addSchema() << " created ... OK.\n";
+
+        Xaction.commit();
+    } catch (const std::exception &e) {
+        std::cerr <<  "\n" << e.what() << std::endl;
+        std::cerr <<  "WARNING: could not create osm-*  tables" << std::endl;
+        std::cerr <<  "   Insertions on osm_* tables are going to be ignored" << std::endl;
+    }
+}
+
+
+
+
+void Export2DB::dropTables() const {
+    try {
+        pqxx::connection db_conn(conninf);
+        pqxx::work Xaction(db_conn);
+
+        Xaction.exec(ways().drop());
+        std::cout << "TABLE: " << ways().addSchema() << " droped ... OK.\n";
+
+        Xaction.exec(vertices().drop());
+        std::cout << "TABLE: " << vertices().addSchema() << " droped ... OK.\n";
+
+        Xaction.exec(pois().drop());
+        std::cout << "TABLE: " << pois().addSchema() << " droped ... OK.\n";
+
+        Xaction.exec(configuration().drop());
+        std::cout << "TABLE: " << configuration().addSchema() << " droped ... OK.\n";
+
+        Xaction.commit();
+    } catch (const std::exception &e) {
+        cerr << e.what() << std::endl;
+        cerr << "ROLLBACK applied";
+    }
+
+    try {
+        pqxx::connection db_conn(conninf);
+        pqxx::work Xaction(db_conn);
+        Xaction.exec(osm_nodes().drop());
+        std::cout << "TABLE: " << osm_nodes().addSchema() << " droped ... OK.\n";
+
+        Xaction.exec(osm_ways().drop());
+        std::cout << "TABLE: " << osm_ways().addSchema() << " droped ... OK.\n";
+
+        Xaction.exec(osm_relations().drop());
+        std::cout << "TABLE: " << osm_relations().addSchema() << " droped ... OK.\n";
+
+        Xaction.commit();
+    } catch (const std::exception &e) {
+        cerr << e.what() << std::endl;
+    }
+}
+
+
+void
+Export2DB::export_configuration(const std::map<std::string, Tag_key>& items) const {
+
+    auto osm_table = m_tables.get_table("configuration");
+
+    std::vector<std::string> values;
+
+    for (const auto &item : items) {
+        auto row = item.second.values(osm_table.columns());
+        values.insert(values.end(), row.begin(), row.end());
+    }
+
+    export_osm(values, osm_table);
+}
+
+
+void
+Export2DB::export_osm(
+        const std::vector<std::string> &values,
+        const Table &table) const {
+    if (values.empty()) return;
+
+    auto columns = table.columns();
+    std::string temp_table(table.temp_name());
+    auto create_sql = table.tmp_create();
+    std::string copy_sql( "COPY " + temp_table + " (" + comma_separated(columns) + ") FROM STDIN");
+
+#if 0
+    std::cout << "\n" << create_sql;
+    std::cout << "\n" << copy_sql;
+
+#endif
+
+    size_t count = 0;
+    try {
+
+
+        pqxx::connection db_con(conninf);
+        pqxx::work Xaction(db_con);
+        PGconn *mycon = PQconnectdb(conninf.c_str());
+
+        PGresult *res = PQexec(mycon, create_sql.c_str());
+        res = PQexec(mycon, copy_sql.c_str());
+        if (res) {};
+
+        for (auto it = values.begin(); it != values.end(); ++it) {
+            auto str = *it;
+
+            ++count;
+
+            PQputline(mycon, str.c_str());
+        }
+
+        PQputline(mycon, "\\.\n");
+
+        if (PQendcopy(mycon) != 0) {
+            Xaction.exec("DROP TABLE " + temp_table);
+            PQfinish(mycon);
+            Xaction.commit();
+
+            if (values.size() < 2) {
+                for (const auto &v : values) {
+                std::cout << "\n*****ERROR HERE:\n" << v << "\n******";
+                }
+                return;
+            }
+            size_t inc = values.size() / 2;
+            export_osm(std::vector<std::string>(values.begin(), values.begin() + inc), table);
+            export_osm(std::vector<std::string>(values.begin() + inc , values.end()), table);
+            return;
+        };
+
+        PQfinish(mycon);
+        Xaction.exec(m_tables.post_process(table));
+        Xaction.exec("DROP TABLE " + temp_table);
+        Xaction.commit();
+    } catch (const std::exception &e) {
+        std::cerr <<  "\n" << e.what() << std::endl;
+        std::cerr << "While exporting to " << table.addSchema() << " TODO insert one by one skip the guilty one\n";
+    }
+}
+
+
+
+
+/*!
+
+*/
+void Export2DB::fill_vertices_table(
+        const std::string &table,
+        const std::string &vertices_tab,
+        pqxx::work &Xaction) const {
+    // 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)");
+    auto result = Xaction.exec(sql);
+
+    std::cout << "\t Vertices inserted: " << result.affected_rows();
+}
+
+
+
+
+
+void Export2DB::fill_source_target(
+        const std::string &table,
+        const std::string &vertices_tab,
+        pqxx::work &Xaction) const {
+    // std::cout << "    Filling 'source' column of '" << table << "':'" << vertices_tab << "'\n";
+    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;");
+    Xaction.exec(sql1);
+
+    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;");
+    Xaction.exec(sql2);
+
+    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::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;");
+    Xaction.exec(sql3);
+}
+
+
+
+
+void Export2DB::exportWays(const Ways &ways, const Configuration &config) const {
+    std::cout << "    Processing " <<  ways.size() <<  " ways"  << ":\n";
+
+    Table table = this->ways();
+
+    auto columns = table.columns();
+    auto ways_columns = comma_separated(columns);
+
+    size_t chunck_size = m_vm["chunk"].as<size_t>();
+
+    auto create_sql = table.tmp_create();
+    auto temp_table(table.temp_name());
+
+    std::string copy_sql( "COPY " + temp_table + " (" + comma_separated(columns) + ") FROM STDIN");
+
+
+    int64_t split_count = 0;
+    int64_t count = 0;
+    size_t start = 0;
+    auto it = ways.begin();
+
+    while (start < ways.size()) {
+        auto limit = (start + chunck_size) < ways.size() ? start + chunck_size : ways.size();
+        try {
+            pqxx::connection db_con(conninf);
+            pqxx::work Xaction(db_con);
+
+            PGconn *mycon = PQconnectdb(conninf.c_str());
+            PGresult *res = PQexec(mycon, create_sql.c_str());
+            res = PQexec(mycon, copy_sql.c_str());
+            if (res) {};
+
+
+            for (auto i = start; i < limit; ++i) {
+                auto way = *it;
+
+                ++count;
+                ++it;
+
+                if (way.tag_config().key() == "" || way.tag_config().value() == "") continue;
+
+                std::vector<std::string> common_values;
+                common_values.push_back(TO_STR(config.tag_value(way.tag_config()).id()));
+                common_values.push_back(TO_STR(way.osm_id()));
+                common_values.push_back(way.maxspeed_forward_str() == "-1" ? TO_STR(config.maxspeed_forward(way.tag_config())) : way.maxspeed_forward_str()) ;
+                common_values.push_back(way.maxspeed_backward_str() == "-1" ? TO_STR(config.maxspeed_backward(way.tag_config())) : way.maxspeed_backward_str()) ;
+                common_values.push_back(way.oneWayType_str());
+                common_values.push_back(way.oneWay());
+                // common_values.push_back(way.has_attribute("oneway") ? way.get_attribute("oneway") : std::string(""));
+                common_values.push_back(TO_STR(config.priority(way.tag_config())));
+
+                auto splits = way.split_me();
+                split_count +=  splits.size();
+                for (size_t j = 0; j < splits.size(); ++j) {
+                    auto length = way.length_str(splits[j]);
+
+                    auto values = common_values;
+                    values.push_back(length);
+                    values.push_back(splits[j].front()->lon());
+                    values.push_back(splits[j].front()->lat());
+                    values.push_back(splits[j].back()->lon());
+                    values.push_back(splits[j].back()->lat());
+                    values.push_back(TO_STR(splits[j].front()->osm_id()));
+                    values.push_back(TO_STR(splits[j].back()->osm_id()));
+                    values.push_back(way.geometry_str(splits[j]));
+
+                    // cost based on oneway
+                    if (way.is_reversed())
+                        values.push_back(std::string("-") + length);
+                    else
+                        values.push_back(length);
+
+                    // reverse_cost
+                    if (way.is_oneway())
+                        values.push_back(std::string("-") + length);
+                    else
+                        values.push_back(length);
+
+                    values.push_back(way.name());
+                    PQputline(mycon, tab_separated(values).c_str());
+                }
+            }
+
+            PQputline(mycon, "\\.\n");
+            PQendcopy(mycon);
+
+            print_progress(ways.size(), count);
+            process_section(ways_columns, Xaction);
+            Xaction.exec("DROP TABLE " + temp_table);
+            Xaction.commit();
+        } catch (const std::exception &e) {
+            std::cerr <<  "\n" << e.what() << std::endl;
+            std::cerr << "While processing FROM " << start << "th \t to: " << limit << "th way\n";
+            std::cerr << "count" << count << " While processing FROM " << start << "th \t to: " << limit << "th way\n";
+        }
+
+        start = limit;
+    }
+}
+
+
+
+void Export2DB::process_section(const std::string &ways_columns, pqxx::work &Xaction) const {
+    //  std::cout << "Creating indices in temporary table\n";
+    auto temp_table(ways().temp_name());
+
+    Xaction.exec("CREATE INDEX "+ temp_table + "_gdx ON "+ temp_table + " using gist(the_geom);");
+    Xaction.exec("CREATE INDEX ON "+ temp_table + "  USING btree (source_osm)");
+    Xaction.exec("CREATE INDEX ON "+ temp_table + "  USING btree (target_osm)");
+
+
+
+
+    //  std::cout << "Deleting  duplicated ways FROM temporary table\n";
+    std::string delete_from_temp(
+            " DELETE FROM "+ temp_table + " a "
+            "     USING " + ways().addSchema() + " b "
+            "     WHERE a.the_geom ~= b.the_geom AND ST_OrderingEquals(a.the_geom, b.the_geom);");
+    Xaction.exec(delete_from_temp);
+
+    //  std::cout << "Updating to existing toplology the temporary table\n";
+    fill_source_target(temp_table, vertices().addSchema(), Xaction);
+
+    //  std::cout << "Inserting new vertices in the vertex table\n";
+    fill_vertices_table(temp_table, vertices().addSchema(), Xaction);
+
+    //  std::cout << "Updating to new toplology the temporary table\n";
+    fill_source_target(temp_table, vertices().addSchema(), Xaction);
+
+
+    //  std::cout << "Inserting new split ways to '" << addSchema(full_table_name("ways")) << "'\n";
+    std::string insert_into_ways(
+            " INSERT INTO " + ways().addSchema() +
+            "(" + ways_columns + ", source, target, length_m, cost_s, reverse_cost_s) "
+            " (SELECT " + ways_columns + ", source, target, length_m, cost_s, reverse_cost_s FROM " + temp_table + "); ");
+    auto result = Xaction.exec(insert_into_ways);
+    std::cout << "\tSplit ways inserted " << result.affected_rows() << "\n";
+}
+
+
+
+
+
+int64_t
+Export2DB::get_val(const std::string sql) const {
+#if 0
+    std::cout << "\nExecuting: \n" << sql << "\n";
+#endif
+    try {
+        pqxx::connection db_conn(conninf);
+        pqxx::work Xaction(db_conn);
+        auto result = Xaction.exec(sql);
+        Xaction.commit();
+        if (result.size() == 0) return 0;
+        return result[0][0].as<int64_t>();
+    } catch (const std::exception &e) {
+        std::cout << "\nWARNING: " << e.what() << std::endl;
+        std::cout <<  sql << "\n";
+    }
+    return 0;
+}
+
+void
+Export2DB::execute(const std::string sql) const {
+#if 0
+    std::cout << "\nExecuting: \n" << sql << "\n";
+#endif
+    try {
+        pqxx::connection db_conn(conninf);
+        pqxx::work Xaction(db_conn);
+        Xaction.exec(sql);
+        Xaction.commit();
+    } catch (const std::exception &e) {
+        std::cout << "\nWARNING: " << e.what() << std::endl;
+        std::cout <<  sql << "\n";
+    }
+}
+
+
+
+/*
+ *
+ *  Integrity of the OSM data IS not ensured so failings are ignored
+ *
+ *  Due to the fact that indexes slow down the process, no index IS created
+ *
+ *  After all the data IS inserted then its time to create indices & foreign keys
+ *
+ */
+void Export2DB::createFKeys() const {
+
+    /*
+     * configuration:
+     */
+    execute(configuration().primary_key("id"));
+    execute(configuration().unique("tag_id"));
+
+    /*
+     * vertices
+     */
+    execute(vertices().primary_key("id"));
+    execute(vertices().unique("osm_id"));
+    execute(vertices().gist_index());
+
+    /*
+     * Ways
+     */
+    execute(ways().primary_key("gid"));
+    execute(ways().foreign_key("source", vertices(), "id"));
+    execute(ways().foreign_key("target", vertices(), "id"));
+    execute(ways().foreign_key("source_osm", vertices(), "osm_id"));
+    execute(ways().foreign_key("target_osm", vertices(), "osm_id"));
+    execute(ways().foreign_key("tag_id", configuration(), "tag_id"));
+    execute(ways().gist_index());
+
+    /*
+     * ponitsOfInterest
+     */
+    execute(pois().primary_key("pid"));
+    execute(pois().gist_index());
+    execute(pois().unique("osm_id"));
+}
+
+void Export2DB::process_pois() const {
+    if (!m_vm.count("addnodes")) return;
+
+    std::cout << "\nAdding functions for processing Points of Interest ..." << endl;
+    /* osm2pgr_pois_update_part_of_topology */
+    execute(pois().sql(0));
+
+
+    /* osm2pgr_pois_update_not_part_of_topology */
+    execute(pois().sql(1));
+
+
+    /* osm2pgr_pois_find_side */
+    execute(pois().sql(2));
+
+
+    /* osm2pgr_pois_new_geom */
+    execute(pois().sql(3));
+
+
+    /* osm2pgr_pois_update */
+    execute(pois().sql(4));
+
+    std::cout << "\nTo process pointsOfInterest table:"
+    "\nosm2pgr_pois_update(radius deault 200, within default 50)\n"
+    "\n  - Using areas of (radius)mts on POIS"
+    "\n  - Using edges that are at least (within) mts of each POI"
+    "\nPOIS that do not have a closest edge is considered as too far\n";
+
+
+    return;
+#if 0
+    std::string array;
+    int64_t total = 0;
+    auto limit = get_val(
+            "SELECT count(*) FROM " + pois().addSchema()
+            + "\n  WHERE vertex_id IS NULL AND edge_id IS NULL");
+
+
+    std::cout << "\nFinding closest edge to " << limit << " Points Of Interest\n";
+    for (int64_t i = 0; i < limit; ++i) {
+        auto curr_tot = get_val(
+                "SELECT osm2pgr_pois_update_not_part_of_topology(200, 50, ARRAY[" + array + "]::BIGINT[])");
+        total += curr_tot;
+
+        if (curr_tot == 0) {
+            auto pid_outOfRange = get_val(" SELECT pid FROM " + pois().addSchema()
+                    +"\n  WHERE vertex_id IS NULL AND edge_id IS NULL"
+                    +"\n  AND pid not in (SELECT unnest(ARRAY[" + array +"]::BIGINT[]))"
+                    +"\n  limit 1;");
+            if (pid_outOfRange == 0) break;
+            if (array.empty()) {
+                array += boost::lexical_cast<std::string>(pid_outOfRange);
+            } else {
+                array += "," + boost::lexical_cast<std::string>(pid_outOfRange);
+            }
+
+            if (get_val(
+                    +"SELECT count(*) FROM (SELECT * FROM " + pois().addSchema()
+                    +"\n  WHERE vertex_id IS NULL AND edge_id IS NULL"
+                    +"\n  AND pid not in (SELECT unnest(ARRAY[" + array +"]::BIGINT[]))) AS a"
+                    ) == 0) break;
+        }
+
+        print_progress(limit, total);
+    }
+
+    if (!array.empty()) {
+        std::cout << "\nNo edge found within distance (200 + 50)mts on pid(s): " << array << "\n";
+    }
+
+    execute("SELECT osm2pgr_pois_find_side()");
+    execute("SELECT osm2pgr_pois_new_geom()");
+    execute(
+            "\n WITH "
+            "\n base AS ("
+            "\n     SELECT pid, w.id AS wid, w.the_geom AS wgeom, p.the_geom AS pgeom"
+            "\n     FROM " + pois().addSchema() + " AS p JOIN " + ways().addSchema() + " AS w ON (edge_id = w.id)"
+            + "\n     WHERE edge_id IS not NULL"
+            + "\n ),"
+
+            + "\n foo AS ("
+            + "\n     SELECT wid, ST_dumppoints(wgeom) AS dp"
+            + "\n     FROM base"
+            + "\n ),"
+
+            + "\n blade AS ("
+            + "\n     SELECT wid, ST_collect((dp).geom) AS blade"
+            + "\n     FROM foo"
+            + "\n     GROUP BY wid"
+            + "\n ),"
+
+            + "\n split AS ("
+            + "\n     SELECT base.*, (ST_Dump(ST_split(wgeom, blade))).geom AS line"
+            + "\n     FROM blade JOIN base"
+            + "\n     USING (wid)"
+            + "\n ),"
+
+            + "\n distance AS ("
+            + "\n     SELECT split.*, ST_distance(line, pgeom) AS dist FROM split"
+            + "\n ),"
+
+            + "\n second AS ("
+            + "\n     SELECT  pid, min(dist) FROM distance GROUP BY pid"
+            + "\n ), "
+
+            + "\n last AS ("
+            + "\n     SELECT pid,"
+            + "\n         (ST_y(ST_startpoint(line)) - ST_y(ST_endpoint(line))) * ST_x(pgeom)"
+            + "\n      +  (ST_x(ST_endpoint(line)) - ST_x(ST_startpoint(line))) * ST_y(pgeom)"
+            + "\n      +  (ST_x(ST_startpoint(line)) * ST_y(ST_endpoint(line)) - ST_x(ST_endpoint(line))"
+            + "\n      * ST_y(ST_startpoint(line))) AS val"
+            + "\n     FROM distance join second using (pid) where dist = min"
+            + "\n )"
+
+            + "\n UPDATE " + pois().addSchema() + " set side = case when val>0 then 'L' when val<0 then 'R' else 'B' end "
+            + "\n FROM last "
+            + "\n WHERE last.pid = " + pois().addSchema() + ".pid;"
+
+            );
+#endif
+}
+
+}  // namespace osm2pgr
diff --git a/src/database/configuration_config.cpp b/src/database/configuration_config.cpp
new file mode 100644
index 0000000..0c8e70f
--- /dev/null
+++ b/src/database/configuration_config.cpp
@@ -0,0 +1,81 @@
+/*PGR-GNU*****************************************************************
+
+ Copyright (c) 2017 pgRouting developers
+ Mail: 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 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.
+********************************************************************PGR-GNU*/
+
+
+#include "boost/lexical_cast.hpp"
+#include "database/table_management.h"
+#include "utilities/utilities.h"
+
+namespace osm2pgr {
+
+
+/*
+ * configuring TABLE configuration
+ */ 
+
+
+Table
+Tables::configuration_config() const {
+    Table table(
+            /* name */
+            "configuration",
+
+            /* schema */
+            m_vm["schema"].as<std::string>(),
+
+            /* full name */
+            "configuration",
+
+            /* standard column creation string */
+            std::string(
+                " id serial"
+                ", tag_id INTEGER"
+                ", tag_key TEXT"
+                ", tag_value TEXT"
+                ", priority double precision"
+                ", maxspeed double precision"
+                ", maxspeed_forward double precision"
+                ", maxspeed_backward double precision"
+                ", force char"),
+
+            /* other columns */
+            "",
+
+            /* geometry */
+            "");
+
+
+
+    std::vector<std::string> columns;
+    columns.push_back("tag_id");
+    columns.push_back("tag_key");
+    columns.push_back("tag_value");
+    columns.push_back("priority");
+    columns.push_back("maxspeed");
+    columns.push_back("maxspeed_forward");
+    columns.push_back("maxspeed_backward");
+    columns.push_back("force");
+
+    table.set_columns(columns);
+
+    return table;
+}
+
+
+} //namespace osm2pgr
diff --git a/src/database/osm_nodes_config.cpp b/src/database/osm_nodes_config.cpp
new file mode 100644
index 0000000..d02a62b
--- /dev/null
+++ b/src/database/osm_nodes_config.cpp
@@ -0,0 +1,82 @@
+/*PGR-GNU*****************************************************************
+
+ Copyright (c) 2017 pgRouting developers
+ Mail: 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 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.
+********************************************************************PGR-GNU*/
+
+#include "boost/lexical_cast.hpp"
+#include "database/table_management.h"
+#include "utilities/utilities.h"
+
+namespace osm2pgr {
+
+
+/*
+ * configuring TABLE osm_nodes
+ */ 
+
+
+Table
+Tables::osm_nodes_config() const {
+    Table table(
+            /* name */
+            std::string("osm_nodes"),
+
+            /* schema */
+            m_vm["schema"].as<std::string>(),
+
+            /* full name */
+            "osm_nodes",
+
+            /* standard column creation string */
+            std::string(
+                " osm_id bigint PRIMARY KEY"
+                + (m_vm.count("attributes") ?
+                    (std::string(", attributes hstore"))
+                    : "")
+                + (m_vm.count("tags") ?
+                    (std::string(", tags hstore"))
+#if 0
+                    (std::string(", tags ") + (m_vm.count("hstore") ? "hstore" : "json"))
+#endif
+                    : "")),
+
+            /* other columns */
+            // TODO get from the configuration maybe this task is to be done on the configuration*/
+            ", tag_name TEXT"
+                ", tag_value TEXT"
+                ", name TEXT ",
+            // end todo
+
+            /* geometry */
+            "POINT");
+    std::vector<std::string> columns;
+    columns.push_back("osm_id");
+    columns.push_back("the_geom");
+    // TODO get from the configuration
+    columns.push_back("tag_name");
+    columns.push_back("tag_value");
+    columns.push_back("name");
+    // end todo
+    if (m_vm.count("attributes")) columns.push_back("attributes");
+    if (m_vm.count("tags")) columns.push_back("tags");
+    table.set_columns(columns);
+
+    return table;
+}
+
+
+} //namespace osm2pgr
diff --git a/src/database/osm_relations_config.cpp b/src/database/osm_relations_config.cpp
new file mode 100644
index 0000000..0e82378
--- /dev/null
+++ b/src/database/osm_relations_config.cpp
@@ -0,0 +1,83 @@
+/*PGR-GNU*****************************************************************
+
+ Copyright (c) 2017 pgRouting developers
+ Mail: 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 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.
+********************************************************************PGR-GNU*/
+
+#include "boost/lexical_cast.hpp"
+#include "database/table_management.h"
+#include "utilities/utilities.h"
+
+namespace osm2pgr {
+
+
+/*
+ * configuring TABLE osm_relations
+ */ 
+
+
+Table
+Tables::osm_relations_config() const {
+    Table table(
+            /* name */
+            "osm_relations",
+
+            /* schema */
+            m_vm["schema"].as<std::string>(),
+
+            /* full name */
+            "osm_relations",
+
+            /* standard column creation string */
+            std::string(
+                " osm_id bigint PRIMARY KEY"
+                " , members hstore"
+                + (m_vm.count("attributes") ?
+                    (std::string(", attributes hstore"))
+                    : "")
+                + (m_vm.count("tags") ?
+                    (std::string(", tags hstore"))
+                    : "")
+                ),
+            /* other columns */
+            // TODO get from the configuration maybe this task is to be done on the configuration*/
+            ", tag_name TEXT"
+                ", tag_value TEXT"
+                ", name TEXT ",
+            // end todo
+
+            /* geometry */
+            "");
+
+
+    std::vector<std::string> columns;
+    columns.push_back("osm_id");
+    columns.push_back("members");
+    // TODO get from the configuration
+    columns.push_back("tag_name");
+    columns.push_back("tag_value");
+    columns.push_back("name");
+    // end todo
+    if (m_vm.count("attributes")) columns.push_back("attributes");
+    if (m_vm.count("tags")) columns.push_back("tags");
+
+    table.set_columns(columns);
+
+    return table;
+}
+
+
+} //namespace osm2pgr
diff --git a/src/database/osm_ways_config.cpp b/src/database/osm_ways_config.cpp
new file mode 100644
index 0000000..b52e742
--- /dev/null
+++ b/src/database/osm_ways_config.cpp
@@ -0,0 +1,88 @@
+/*PGR-GNU*****************************************************************
+
+ Copyright (c) 2017 pgRouting developers
+ Mail: 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 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.
+********************************************************************PGR-GNU*/
+
+#include "database/table_management.h"
+#include "utilities/utilities.h"
+#include <vector>
+
+namespace osm2pgr {
+
+
+/*
+ * configuring TABLE osm_ways
+ */ 
+
+
+Table
+Tables::osm_ways_config() const {
+    Table table(
+            /* name */
+            "osm_ways",
+
+            /* schema */
+            m_vm["schema"].as<std::string>(),
+
+            /* full name */
+            "osm_ways",
+
+            /* standard column creation string */
+            std::string(
+                " osm_id bigint PRIMARY KEY"
+                " , members hstore"
+                + (m_vm.count("attributes") ?
+                    (std::string(", attributes hstore"))
+                    : "")
+                + (m_vm.count("tags") ?
+                    (std::string(", tags hstore"))
+#if 0
+                    (std::string(", tags ") + (m_vm.count("hstore") ? "hstore" : "json"))
+#endif
+                    : "")),
+
+            /* other columns */
+            /* TODO get from the configuration maybe this task is to be done on the configuration*/
+            std::string(
+                    ", tag_name TEXT"
+                    ", tag_value TEXT"
+                    ", name TEXT "),
+            // end todo
+
+            /* geometry */
+            "LINESTRING");
+
+
+    std::vector<std::string> columns;
+    columns.push_back("osm_id");
+    columns.push_back("members");
+    // TODO get from the configuration
+    columns.push_back("tag_name");
+    columns.push_back("tag_value");
+    columns.push_back("name");
+    // end todo
+    if (m_vm.count("attributes")) columns.push_back("attributes");
+    if (m_vm.count("tags")) columns.push_back("tags");
+    columns.push_back("the_geom");
+
+    table.set_columns(columns);
+
+    return table;
+}
+
+
+} //namespace osm2pgr
diff --git a/src/database/pois_config.cpp b/src/database/pois_config.cpp
new file mode 100644
index 0000000..65b6653
--- /dev/null
+++ b/src/database/pois_config.cpp
@@ -0,0 +1,89 @@
+/*PGR-GNU*****************************************************************
+
+ Copyright (c) 2017 pgRouting developers
+ Mail: 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 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.
+********************************************************************PGR-GNU*/
+
+#include "boost/lexical_cast.hpp"
+#include "database/table_management.h"
+#include "utilities/utilities.h"
+
+namespace osm2pgr {
+
+
+/*
+ * configuring TABLE osm_nodes
+ */ 
+
+
+Table
+Tables::pois_config() const {
+    Table table(
+            /* name */
+            std::string("pointsofinterest"),
+
+            /* schema */
+            m_vm["schema"].as<std::string>(),
+
+            /* full name */
+            std::string(
+                m_vm["prefix"].as<std::string>()
+                + "pointsofinterest"
+                + m_vm["suffix"].as<std::string>()),
+
+
+            /* standard column creation string */
+            std::string(
+                "  pid bigserial"
+                ", osm_id bigint"
+                ", vertex_id bigint"
+                ", edge_id bigint"
+                ", side CHAR"
+                ", fraction FLOAT"
+                ", length_m FLOAT"
+                + (m_vm.count("attributes") ?
+                    (std::string(", attributes hstore"))
+                    : "")
+                + (m_vm.count("tags") ?
+                    (std::string(", tags hstore"))
+                    : "")),
+
+            /* other columns */
+            std::string(
+                    ", tag_name TEXT"
+                    ", tag_value TEXT"
+                    ", name TEXT "),
+            // end todo
+
+            /* geometry */
+            "POINT");
+    std::vector<std::string> columns;
+    columns.push_back("osm_id");
+    columns.push_back("the_geom");
+    // TODO get from the configuration
+    columns.push_back("tag_name");
+    columns.push_back("tag_value");
+    columns.push_back("name");
+    // end todo
+    if (m_vm.count("attributes")) columns.push_back("attributes");
+    if (m_vm.count("tags")) columns.push_back("tags");
+    table.set_columns(columns);
+
+    return table;
+}
+
+
+} //namespace osm2pgr
diff --git a/src/database/table_management.cpp b/src/database/table_management.cpp
new file mode 100644
index 0000000..b30b636
--- /dev/null
+++ b/src/database/table_management.cpp
@@ -0,0 +1,444 @@
+/*PGR-GNU*****************************************************************
+
+ Copyright (c) 2017 pgRouting developers
+ Mail: 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 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.
+********************************************************************PGR-GNU*/
+
+
+#include <unistd.h>
+
+#include "boost/lexical_cast.hpp"
+#include "database/table_management.h"
+#include "utilities/utilities.h"
+
+namespace osm2pgr {
+
+Table::Table(
+        const std::string &name,
+        const std::string &schema,
+        const std::string &full_name,
+
+        const std::string &create_str,
+        const std::string &other_columns,
+        const std::string &geometry
+        ):
+    m_name(name),
+    m_schema(schema),
+    m_full_name(full_name),
+
+    m_create(create_str),
+    m_other_columns(other_columns),
+    m_geometry(geometry)
+    { }
+
+std::string
+Table::gist_index() const {
+    return "CREATE INDEX ON " + addSchema()
+        + "\n  USING GIST (the_geom);";
+}
+
+
+std::string
+Table::foreign_key(
+        const std::string &column,
+        const Table &table,
+        const std::string &table_column) const {
+    return "ALTER TABLE " + addSchema()
+        + "\n  ADD FOREIGN KEY (" + column + ")"
+        + "\n  REFERENCES " + table.addSchema() + "(" + table_column + ")"
+        + "\n  ON UPDATE NO ACTION \n  ON DELETE NO ACTION;";
+}
+
+
+std::string
+Table::unique(const std::string &column) const {
+    return std::string("ALTER TABLE " + addSchema()
+        + "\n  ADD UNIQUE (" + column + ")");
+}
+
+std::string
+Table::primary_key(const std::string &column) const {
+    return std::string("ALTER TABLE " + addSchema()
+        + "\n  ADD PRIMARY KEY (" + column + ")");
+}
+
+
+
+void 
+Table::set_columns(const std::vector<std::string> &columns) {
+    m_columns = columns;
+}
+
+std::string
+Table::addSchema() const {
+    return
+        m_schema
+        + (m_schema == "" ? "" :  ".")
+        + m_full_name;
+}
+
+
+
+/*
+ * sql strings
+ */
+
+std::string
+Table::create() const {
+    std::string sql =
+        "CREATE TABLE " + addSchema() + " ("
+        + m_create
+        + m_other_columns
+        + m_constraint + ")";
+
+    sql += " WITH (autovacuum_enabled = false);";
+
+    if (m_geometry != "") {
+        sql += "SELECT AddGeometryColumn('"
+            + m_schema
+            + (m_schema == "" ? "" : "', '")
+            + table_name() + "', 'the_geom', 4326, '" + m_geometry + "', 2);";
+
+        if (name() == "pointsofinterest") {
+            sql += "SELECT AddGeometryColumn('"
+                + m_schema
+                + (m_schema == "" ? "" : "', '")
+                + table_name() + "', 'new_geom', 4326, '" + m_geometry + "', 2);";
+        }
+    }
+
+
+    return sql;
+}
+
+
+std::string
+Table::drop() const {
+    return "DROP TABLE IF EXISTS " + addSchema() + ";";
+}
+
+
+std::string
+Table::temp_name() const {
+    return
+        "__" 
+        + table_name() 
+        + boost::lexical_cast<std::string>(getpid());
+}
+
+
+std::string
+Table::tmp_create() const {
+    std::string sql =
+        "CREATE UNLOGGED TABLE " 
+        + temp_name()
+        + " ("
+        + m_create
+        + m_other_columns
+        + ");";
+    if (m_geometry != "") {
+        sql += "SELECT AddGeometryColumn('"
+            + temp_name() + "', 'the_geom', 4326, '" + m_geometry + "', 2);";
+    }
+    return sql;
+}
+
+
+std::string
+Tables::post_process(const Table &table) const  {
+    if (table.name() == "osm_nodes"
+            || table.name() == "pointsofinterest"
+            || table.name() == "osm_ways"
+            || table.name() == "osm_relations") { 
+        std::string str(
+                " WITH data AS ("
+                " SELECT a.* "
+                " FROM  " + table.temp_name() + " a LEFT JOIN  " + table.addSchema() + " b USING (osm_id) WHERE (b.osm_id IS NULL))"
+
+                + " INSERT INTO "  +  table.addSchema() 
+                + "(" + comma_separated(table.columns()) + ") "
+                + " (SELECT " + comma_separated(table.columns()) + " FROM data); ");
+        return str;
+    } else if (table.name() == "configuration") {
+
+        std::string str(
+                " WITH data AS ("
+                " SELECT a.* "
+                " FROM  " + configuration().temp_name() + " a LEFT JOIN  " + configuration().addSchema() + " b USING (tag_id) WHERE (b.tag_id IS NULL))"
+
+                + " INSERT INTO "  +  configuration().addSchema() 
+                + "(" + comma_separated(configuration().columns()) + ") "
+                + " (SELECT " + comma_separated(configuration().columns()) + " FROM data); ");
+        return str;
+    }
+    return "";
+}
+
+
+
+Tables::Tables(const  po::variables_map &vm) :
+    m_vm(vm),
+    /*
+     * initializing tables
+     */
+    m_ways(ways_config()),
+    m_ways_vertices_pgr(ways_vertices_pgr_config()),
+    m_points_of_interest(pois_config()),
+    m_configuration(configuration_config()),
+
+    m_osm_nodes(osm_nodes_config()),
+    m_osm_ways(osm_ways_config()),
+    m_osm_relations(osm_relations_config())
+{
+    m_points_of_interest.add_sql(
+            "\nCREATE OR REPLACE FUNCTION osm2pgr_pois_update_part_of_topology()"
+            "\nRETURNS BIGINT AS"
+            "\n$$"
+            "\n-----------------------------------------------------------------"
+            "\n-- When the point of interest is part of the routing topology"
+            "\n--  Sets the vid value to the corresponding id of the vertices table"
+            "\n--  The distance from the routing topólogy to the point of Interest is 0"
+            "\n-----------------------------------------------------------------\n"
+            "\nDECLARE"
+            "\n  curr_tot BIGINT;"
+            "\nBEGIN"
+              "\n  UPDATE " +  pois().addSchema() + " AS pois"
+            + "\n      SET (vertex_id, length_m) = (vertices.id, 0)"
+            + "\n    FROM " + vertices().addSchema() + " AS vertices"
+            + "\n    WHERE vertex_id IS NULL AND pois.osm_id = vertices.osm_id;"
+            + "\n  GET DIAGNOSTICS curr_tot = ROW_COUNT;"
+            + "\n  RETURN curr_tot;"
+            + "\nEND;"
+            + "\n$$"
+            + "\nLANGUAGE plpgsql;"
+            + "\nCOMMENT ON FUNCTION osm2pgr_pois_update_part_of_topology()"
+            + "\n  IS 'osm2pgrouting generated function';"
+            );
+
+
+    m_points_of_interest.add_sql(
+            "CREATE OR REPLACE FUNCTION osm2pgr_pois_update_not_part_of_topology(radius FLOAT, within FLOAT, tooFar BIGINT[])"
+            "\n RETURNS BIGINT AS"
+            "\n $$"
+            "\n-----------------------------------------------------------------"
+            "\n-- When A point of interest is NOT part of the routing topology"
+            "\n--  Looks for a POI that has not being assigned a vid or an edge_id"
+            "\n--  - grabs all the POIS that are within the (radius) mts distance of the POI"
+            "\n--  - grabs all the edges that are within the (radius + within)mts of the POI"
+            "\n--  - FOR each POI in POIS"
+            "\n--    - For closest edge to the POI:"
+            "\n--      - if the closest point in the edge to the POI is the an ending vertex:"
+            "\n--        - Sets the vid value to the corresponding id of the vertices table"
+            "\n--      - if the closest point in the edge to the POI is NOT an ending vertex:"
+            "\n--        - Sets the edge_id and the fraction values"
+            "\n-----------------------------------------------------------------"
+            "\n DECLARE"
+            "\n    curr_tot BIGINT;"
+            "\n BEGIN"
+            "\n        WITH "
+            "\n        poi AS ("
+            "\n            SELECT ST_buffer(the_geom::geography, $1)::geometry AS bufferPois,"
+            "\n            ST_buffer(the_geom::geography, $1 + $2)::geometry AS bufferWays"
+            "\n            FROM " + pois().addSchema()
+            +"\n            WHERE vertex_id IS NULL AND edge_id IS NULL"
+            +"\n            AND pid not in (SELECT unnest(tooFar))"
+            +"\n            limit 1"
+            +"\n        ),"
+            +"\n        pois AS ("
+            +"\n            SELECT * FROM " + pois().addSchema() + ", poi"
+            +"\n            WHERE ST_Within(the_geom, bufferPois) "
+            +"\n            AND vertex_id IS NULL AND edge_id IS NULL"
+            +"\n            AND pid not in (SELECT unnest(tooFar))"
+            +"\n        ),"
+            +"\n        wayss AS ("
+            +"\n            SELECT * FROM " + ways().addSchema() + ", poi"
+            +"\n            WHERE ST_Intersects(the_geom, bufferWays)"
+            +"\n        ),"
+            +"\n        first AS ("
+            +"\n            SELECT   ways.gid AS wid,"
+            +"\n            source_osm, target_osm,"
+            +"\n            ST_distance(pois.the_geom::geography,   ways.the_geom::geography) AS dist,"
+            +"\n            pois.osm_id AS vid,"
+            +"\n            ST_linelocatepoint(ways.the_geom, pois.the_geom) AS fraction"
+            +"\n            FROM  wayss AS ways , pois"
+            +"\n            WHERE pois.vertex_id IS NULL AND pois.edge_id IS NULL"
+            +"\n        ),"
+
+            +"\n        second AS ("
+            +"\n            SELECT  vid, min(dist) FROM first group by vid"
+            +"\n       ),"
+
+
+            +"\n        third  AS ("
+            +"\n            SELECT first.vid, NULL::bigint AS wid, NULL::FLOAT AS fraction, first.dist, source_osm AS v_osm_id FROM first, second WHERE dist = min AND fraction in (0)"
+            +"\n            UNION "
+            +"\n            SELECT first.vid, NULL::bigint AS wid, NULL::FLOAT AS fraction, first.dist, target_osm AS v_osm_id FROM first, second WHERE dist = min AND fraction in (1)"
+            +"\n        ),"
+            +"\n        last AS ("
+            +"\n            SELECT third.*, b.id  FROM third join " +  vertices().addSchema() + " AS b ON (third.v_osm_id = b.osm_id)"
+            +"\n            UNION"
+            +"\n            SELECT first.vid, first.wid, first.fraction, first.dist, NULL AS v_osm_id, NULL::bigint AS id FROM first, second WHERE dist = min AND fraction not in (0, 1)"
+            +"\n        )"
+
+            +"\n        UPDATE " + pois().addSchema() +" AS pois   SET (vertex_id, edge_id, fraction, length_m) = (last.id, last.wid, last.fraction, last.dist)"
+            +"\n        FROM last WHERE  pois.osm_id = last.vid;"
+            +"\n        GET DIAGNOSTICS curr_tot = ROW_COUNT;"
+            +"\n    return curr_tot;"
+            +"\n END;"
+            +"\n $$"
+            +"\n LANGUAGE plpgsql;"
+            +"\nCOMMENT ON FUNCTION osm2pgr_pois_update_not_part_of_topology(float,float,bigint[])"
+            + "\n  IS 'osm2pgrouting generated function';"
+            );
+
+    m_points_of_interest.add_sql(
+            "CREATE OR REPLACE FUNCTION osm2pgr_pois_find_side()"
+            "\n RETURNS VOID AS"
+            "\n $$"
+            "\n WITH "
+            "\n base AS ("
+            "\n     SELECT pid, w.gid AS wid, w.the_geom AS wgeom, p.the_geom AS pgeom"
+            "\n     FROM " + pois().addSchema() + " AS p JOIN " + ways().addSchema() + " AS w ON (edge_id = w.gid)"
+            + "\n     WHERE edge_id IS NOT NULL AND side IS NULL"
+            + "\n ),"
+
+            + "\n foo AS ("
+            + "\n     SELECT wid, ST_dumppoints(wgeom) AS dp"
+            + "\n     FROM base"
+            + "\n ),"
+
+            + "\n blade AS ("
+            + "\n     SELECT wid, ST_collect((dp).geom) AS blade"
+            + "\n     FROM foo"
+            + "\n     GROUP BY wid"
+            + "\n ),"
+
+            + "\n split AS ("
+            + "\n     SELECT base.*, (ST_Dump(ST_split(wgeom, blade))).geom AS line"
+            + "\n     FROM blade JOIN base"
+            + "\n     USING (wid)"
+            + "\n ),"
+
+            + "\n distance AS ("
+            + "\n     SELECT split.*, ST_distance(line, pgeom) AS dist FROM split"
+            + "\n ),"
+
+            + "\n second AS ("
+            + "\n     SELECT  pid, min(dist) FROM distance GROUP BY pid"
+            + "\n ), "
+
+            + "\n last AS ("
+            + "\n     SELECT pid,"
+            + "\n         (ST_y(ST_startpoint(line)) - ST_y(ST_endpoint(line))) * ST_x(pgeom)"
+            + "\n      +  (ST_x(ST_endpoint(line)) - ST_x(ST_startpoint(line))) * ST_y(pgeom)"
+            + "\n      +  (ST_x(ST_startpoint(line)) * ST_y(ST_endpoint(line)) - ST_x(ST_endpoint(line))"
+            + "\n      * ST_y(ST_startpoint(line))) AS val"
+            + "\n     FROM distance join second using (pid) where dist = min"
+            + "\n )"
+
+            + "\n UPDATE " + pois().addSchema() + " set side = case when val>0 then 'L' when val<0 then 'R' else 'B' end "
+            + "\n FROM last "
+            + "\n WHERE last.pid = " + pois().addSchema() + ".pid;"
+            +"\n $$"
+            +"\n LANGUAGE sql;"
+            +"\nCOMMENT ON FUNCTION osm2pgr_pois_find_side()"
+            + "\n  IS 'osm2pgrouting generated function';"
+            );
+
+    m_points_of_interest.add_sql(
+            "CREATE OR REPLACE FUNCTION osm2pgr_pois_new_geom()"
+            "\n RETURNS VOID AS"
+            "\n $$"
+            "\n UPDATE " + pois().addSchema()
+            + "\n     SET new_geom = ST_LineInterpolatePoint(e.the_geom, fraction)"
+            + "\n         FROM " + ways().addSchema() + " AS e WHERE edge_id = gid;"
+
+            "\n UPDATE " + pois().addSchema()
+            + "\n     SET new_geom = the_geom"
+            + "\n         WHERE vertex_id IS NOT NULL;"
+            + "\n $$"
+            + "\n LANGUAGE sql;"
+            +"\nCOMMENT ON FUNCTION osm2pgr_pois_new_geom()"
+            + "\n  IS 'osm2pgrouting generated function';"
+            );
+
+
+    m_points_of_interest.add_sql(
+            "\nCREATE OR REPLACE FUNCTION osm2pgr_pois_update(radius FLOAT DEFAULT 200, within FLOAT DEFAULT 50)"
+
+            "\n RETURNS BIGINT AS"
+            "\n $$"
+            "\n-----------------------------------------------------------------"
+            "\n-- Cycles thru all the POIS to either:"
+            "\n--  Sets the vid value to the corresponding id of the vertices table"
+            "\n--  Set the edge_id & disance"
+            "\n--  Sets the side"
+            "\n-- "
+            "\n-- By working on areas of (radius)mts on POIS"
+            "\n-- looking on edges that are at least (within) mts of each POI"
+            "\n-- POIS that do not have a closest edge is considered as tooFar"
+            "\n-- "
+            "\n-- TooFar: are the POIS that do not have a closest edge within (radius + within)mts"
+            "\n-- Recommended values radius = 200, within 50 mts"
+            "\n-----------------------------------------------------------------\n"
+            "\n DECLARE"
+            "\n    curr_tot BIGINT;"
+            "\n    total BIGINT :=0;"
+            "\n    rec RECORD;"
+            "\n    factor FLOAT = 0.5;"
+            "\n    tooFar BIGINT[];"
+            "\n BEGIN"
+            "\n    total = osm2pgr_pois_update_part_of_topology();"
+
+            "\n    SELECT count(*) FROM " + pois().addSchema()
+            +"\n    WHERE vertex_id IS NULL AND edge_id IS NULL"
+            +"\n    INTO rec; "
+
+            +"\n    FOR i IN 1..rec.count LOOP"
+            +"\n        curr_tot = osm2pgr_pois_update_not_part_of_topology(radius, within, tooFar);"
+
+            +"          RAISE NOTICE '%: Updated % points of Interest', i, curr_tot;"
+            +"\n        total := total + curr_tot;"
+            +"\n        IF (curr_tot = 0) THEN"
+            +"\n            SELECT pid FROM " + pois().addSchema()
+            +"\n                WHERE vertex_id IS NULL AND edge_id IS NULL"
+            +"\n                AND pid not in (SELECT unnest(tooFar))"
+            +"\n                limit 1 INTO rec;"
+            +"\n            raise notice 'Not within range: pid = %', rec.pid;"
+            +"\n            tooFar := tooFar || rec.pid;"
+            +"\n            SELECT count(*) FROM (SELECT * FROM " + pois().addSchema()
+            +"\n                WHERE vertex_id IS NULL AND edge_id IS NULL"
+            +"\n                AND pid not in (SELECT unnest(tooFar)) LIMIT 1) a  INTO rec;"
+
+            +"\n            EXIT WHEN rec.count = 0;"
+            +"\n        END IF;"
+            +"\n    END LOOP;"
+            +"\n    PERFORM osm2pgr_pois_find_side();"
+            +"\n    PERFORM osm2pgr_pois_new_geom();"
+
+            +"\n    return total;"
+            +"\n END;"
+            +"\n $$"
+            +"\n LANGUAGE plpgsql;"
+            +"\nCOMMENT ON FUNCTION osm2pgr_pois_update(float, float)"
+            + "\n  IS 'osm2pgrouting generated function. osm2pgr_pois_update(radius, within)\nworking on areas of (radius)mts\nOn edges that are at least (within) mts of each POI';"
+            );
+
+
+}
+
+
+} // namespace osm2pgr
diff --git a/src/database/ways_config.cpp b/src/database/ways_config.cpp
new file mode 100644
index 0000000..7b21871
--- /dev/null
+++ b/src/database/ways_config.cpp
@@ -0,0 +1,130 @@
+/*PGR-GNU*****************************************************************
+
+ Copyright (c) 2017 pgRouting developers
+ Mail: 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 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.
+********************************************************************PGR-GNU*/
+
+#include "boost/lexical_cast.hpp"
+#include "database/table_management.h"
+#include "utilities/utilities.h"
+#include <string>
+
+namespace osm2pgr {
+
+
+/*
+ * configuring TABLE osm_nodes
+ */ 
+
+
+Table
+Tables::ways_config() const {
+    Table table(
+            /* name */
+            "ways",
+
+            /* schema */
+            m_vm["schema"].as<std::string>(),
+
+            /* full name */
+            std::string(
+                m_vm["prefix"].as<std::string>()
+                + "ways"
+                + m_vm["suffix"].as<std::string>()),
+
+            /* standard column creation string */
+            std::string(
+                " gid bigserial"
+                ", osm_id bigint"
+                ", tag_id integer"
+
+                ", length double precision"
+                ", length_m double precision"
+                ", name text"
+                ", source bigint"
+                ", target bigint"
+                ", source_osm bigint"
+                ", target_osm bigint"
+
+                ", cost double precision"
+                ", reverse_cost double precision"
+                ", cost_s double precision "
+                ", reverse_cost_s double precision"
+                ", rule text"
+                ", one_way int "
+                ", oneway TEXT "
+
+                ", x1 double precision"
+                ", y1 double precision"
+                ", x2 double precision"
+                ", y2 double precision"
+
+                ", maxspeed_forward double precision"
+                ", maxspeed_backward double precision"
+                ", priority double precision DEFAULT 1"
+#if 0
+                + (m_vm.count("attributes") ?
+                        (std::string(", attributes ") + (m_vm.count("hstore") ? "hstore" : "json"))
+                        : "")
+                + (m_vm.count("tags") ?
+                        (std::string(", tags ") + (m_vm.count("hstore") ? "hstore" : "json"))
+                        : "")
+#endif
+                ),
+
+            /* other columns */
+            "",
+
+            /* geometry */
+            "LINESTRING");
+
+
+    std::vector<std::string> columns;
+    columns.push_back("tag_id");
+    columns.push_back("osm_id");
+    columns.push_back("maxspeed_forward");
+    columns.push_back("maxspeed_backward");
+    columns.push_back("one_way");
+    columns.push_back("oneway");
+    columns.push_back("priority");
+
+    columns.push_back("length");
+    columns.push_back("x1"); columns.push_back("y1");
+    columns.push_back("x2"); columns.push_back("y2");
+    columns.push_back("source_osm");
+    columns.push_back("target_osm");
+    columns.push_back("the_geom");
+    columns.push_back("cost");
+    columns.push_back("reverse_cost");
+    columns.push_back("name");
+
+
+#if 0
+    // TODO get from the configuration
+    columns.push_back("tag_name");
+    columns.push_back("tag_value");
+
+    // end todo
+    if (m_vm.count("attributes")) columns.push_back("attributes");
+    if (m_vm.count("tags")) columns.push_back("tags");
+#endif
+    table.set_columns(columns);
+
+    return table;
+}
+
+
+} //namespace osm2pgr
diff --git a/src/database/ways_vertices_pgr_config.cpp b/src/database/ways_vertices_pgr_config.cpp
new file mode 100644
index 0000000..315ebb0
--- /dev/null
+++ b/src/database/ways_vertices_pgr_config.cpp
@@ -0,0 +1,79 @@
+/*PGR-GNU*****************************************************************
+
+ Copyright (c) 2017 pgRouting developers
+ Mail: 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 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.
+********************************************************************PGR-GNU*/
+
+#include "boost/lexical_cast.hpp"
+#include "database/table_management.h"
+#include "utilities/utilities.h"
+#include <string>
+
+namespace osm2pgr {
+
+
+/*
+ * configuring TABLE osm_nodes
+ */ 
+
+
+Table
+Tables::ways_vertices_pgr_config() const {
+    Table table(
+            /* name */
+            "ways_vertices_pgr",
+
+            /* schema */
+            m_vm["schema"].as<std::string>(),
+
+            /* full name */
+            std::string(
+                m_vm["prefix"].as<std::string>()
+                + "ways"
+                + m_vm["suffix"].as<std::string>()
+                + "_vertices_pgr"),
+
+            /* standard column creation string */
+            std::string(
+                " id bigserial"
+                ", osm_id bigint"
+                ", eout integer"
+                ", lon decimal(11,8)"
+                ", lat decimal(11,8)"
+                ", cnt integer"
+                ", chk integer"
+                ", ein integer"
+#if 0
+                + (m_vm.count("attributes") ?
+                    (std::string(", attributes ") + (m_vm.count("hstore") ? "hstore" : "json"))
+                    : "")
+                + (m_vm.count("tags") ?
+                    (std::string(", tags ") + (m_vm.count("hstore") ? "hstore" : "json"))
+                    : "")
+#endif
+                ),
+
+                /* other columns */
+                "",
+
+                /* geometry */
+                "POINT");
+
+            return table;
+}
+
+
+} //namespace osm2pgr
diff --git a/src/osm_element.cpp b/src/osm_element.cpp
deleted file mode 100644
index 1b61c26..0000000
--- a/src/osm_element.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/***************************************************************************
- *   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/Node.cpp b/src/osm_elements/Node.cpp
similarity index 82%
rename from src/Node.cpp
rename to src/osm_elements/Node.cpp
index d24ba4e..2a6a0d8 100644
--- a/src/Node.cpp
+++ b/src/osm_elements/Node.cpp
@@ -28,8 +28,8 @@
 #include <map>
 #include <cassert>
 #include <math.h>
-#include "./osm_tag.h"
-#include "./Node.h"
+#include "osm_elements/osm_tag.h"
+#include "osm_elements/Node.h"
 
 namespace osm2pgr {
 
@@ -41,14 +41,21 @@ Node::Node(const char **atts) :
         assert(has_attribute("lon"));
     }
 
+void 
+Node::tag_config(const Tag &tag) {
+    Element::tag_config(tag);
+    ++m_numsOfUse;
+    ++m_numsOfUse;
+}
+
 
 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));
+    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;
 
@@ -67,4 +74,6 @@ Node::getLength(const Node &previous) const {
 #endif
 }
 
+
+
 }  // namespace osm2pgr
diff --git a/src/osm_elements/OSMDocument.cpp b/src/osm_elements/OSMDocument.cpp
new file mode 100644
index 0000000..0735a21
--- /dev/null
+++ b/src/osm_elements/OSMDocument.cpp
@@ -0,0 +1,267 @@
+/***************************************************************************
+ *   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 "osm_elements/OSMDocument.h"
+
+#include <boost/lexical_cast.hpp>
+#include <vector>
+#include <map>
+#include <utility>
+#include <string>
+#include <iostream>
+#include <algorithm>
+
+#if 0
+#include <sys/wait.h>
+#endif
+
+#include "utilities/utilities.h"
+#include "configuration/configuration.h"
+#include "osm_elements/Node.h"
+#include "osm_elements/Relation.h"
+#include "osm_elements/Way.h"
+#include "database/Export2DB.h"
+
+namespace osm2pgr {
+
+OSMDocument::OSMDocument(
+        const Configuration &config,
+        const po::variables_map &vm,
+        const Export2DB &db_conn,
+        size_t lines) :
+    m_rConfig(config),
+    m_vm(vm),
+    m_db_conn(db_conn),
+    m_chunk_size(vm["chunk"].as<size_t>()),
+    m_nodeErrs(0),
+    m_lines(lines) {
+}
+
+
+void
+OSMDocument::wait_child() const {
+#if 0
+    while (true) {
+        int status;
+        pid_t done = wait(&status);
+        if (done == -1) {
+            if (errno == ECHILD) break; // no more child processes
+        } else {
+            if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
+                cerr << "pid " << done << " failed" << endl;
+                exit(1);
+            }
+        }
+    }
+#endif
+}
+
+
+void
+OSMDocument::AddNode(const Node &n) {
+    if (m_vm.count("addnodes")) {
+        if ((m_nodes.size() % m_chunk_size) == 0) {
+            wait_child();
+            std::cout << "\rCurrent osm_nodes:\t" << m_nodes.size();
+            osm_table_export(m_nodes, "osm_nodes");
+            export_pois();
+        }
+    }
+
+    m_nodes.push_back(n);
+}
+
+void OSMDocument::AddWay(const Way &w) {
+    if (m_ways.empty() && m_vm.count("addnodes")) {
+        wait_child();
+        osm_table_export(m_nodes, "osm_nodes");
+        std::cout << "\nFinal osm_nodes:\t" << m_nodes.size();
+        export_pois();
+    }
+
+
+    if (m_vm.count("addnodes")) {
+        if ((m_ways.size() % m_chunk_size) == 0) {
+            wait_child();
+            if (m_ways.size() % 200000 == 0) {
+                std::cout << "\nCurrent osm_ways:\t" << m_ways.size();
+            }
+            osm_table_export(m_ways, "osm_ways");
+        }
+    }
+
+    m_ways.push_back(w);
+}
+
+void
+OSMDocument::AddRelation(const Relation &r) {
+    if (m_vm.count("addnodes") && m_relations.empty()) {
+        wait_child();
+        osm_table_export(m_ways, "osm_ways");
+        std::cout << "\nFinal osm_ways:\t" << m_ways.size();
+    }
+
+    if (m_vm.count("addnodes")) {
+        wait_child();
+        if (m_relations.size() % 100000 == 0) {
+            std::cout << "\nCurrent osm_relations:\t" << m_relations.size();
+        }
+        osm_table_export(m_relations, "osm_relations");
+    }
+    m_relations.push_back(r);
+}
+
+void
+OSMDocument::endOfFile() const {
+    if (m_vm.count("addnodes")) {
+        wait_child();
+        osm_table_export(m_relations, "osm_relations");
+        std::cout << "\nEnd Of file\n\n\n";
+    }
+}
+
+
+template <typename T>
+static
+bool
+less(const T &item, const int64_t &id) {
+    return item.osm_id() < id;
+}
+
+
+Node*
+OSMDocument::FindNode(int64_t node_id) {
+    auto it = std::lower_bound(m_nodes.begin(), m_nodes.end(), node_id, less<Node>); 
+    return &*it;
+}
+
+bool
+OSMDocument::has_node(int64_t node_id) const {
+    auto it = std::lower_bound(m_nodes.begin(), m_nodes.end(), node_id, less<Node>); 
+    return (it != m_nodes.end());
+}
+
+Way*
+OSMDocument::FindWay(int64_t way_id) {
+    auto it = std::lower_bound(m_ways.begin(), m_ways.end(), way_id, less<Way>); 
+    return &*it;
+}
+
+bool
+OSMDocument::has_way(int64_t way_id) const {
+    auto it = std::lower_bound(m_ways.begin(), m_ways.end(), way_id, less<Way>); 
+    return (it != m_ways.end());
+}
+
+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;
+    way.add_node(node_id);
+
+#if 1
+    // TODO leave this when splitting
+    if (!has_node(node_id)) {
+        ++m_nodeErrs;
+    } else {
+        auto node = FindNode(node_id);
+        node->incrementUse();
+        way.add_node(node);
+    }
+#endif
+}
+
+/*
+ * for example
+ *  <tag highway="kerb">
+ *  
+ *
+ * And the configuration file has:
+ * <type name="highway" id="1">
+ *     <class name="kerb" id="101" priority="1.0" maxspeed="130" />
+ *
+ */
+
+void
+OSMDocument::add_config(Element *item, const Tag &tag) const {
+    auto  k = tag.key();
+    auto  v = tag.value();
+    if (config_has_tag(tag)) {
+        if (!(item->is_tag_configured())
+                || (config_has_tag(item->tag_config())
+                    && m_rConfig.priority(tag) < m_rConfig.priority(item->tag_config())
+                   )) {
+            item->tag_config(tag);
+        }
+    }
+}
+
+static
+bool
+has_no_tags(const Node &node) {
+    return !node.has_tags();
+}
+
+void
+OSMDocument::export_pois() const {
+    std::string table("pointsofinterest");
+    if (m_nodes.empty()) return;
+
+#if 0
+    if (m_vm.count("fork")) {
+        auto pid = fork();
+        if (pid < 0) {
+            std::cerr << "Failed to fork" << endl;
+            exit(1);
+        }
+        if (pid > 0) return;
+    }
+#endif
+
+
+    auto residue = m_nodes.size() % m_chunk_size;
+    size_t start = residue? m_nodes.size() - residue : m_nodes.size() - m_chunk_size;
+
+    auto export_items = Nodes(m_nodes.begin() + start, m_nodes.end());
+    /*
+     * deleting nodes with no tag information
+     */
+    export_items.erase(
+            std::remove_if(export_items.begin(), export_items.end(), has_no_tags),
+            export_items.end());
+
+    if (!export_items.empty()) {
+        m_db_conn.export_osm(export_items, table);
+    }
+
+#if 0
+    if (m_vm.count("fork")) {
+        /*
+         * finish the child process
+         */
+        _exit(0);
+    }
+#endif
+}
+
+
+}  // namespace osm2pgr
diff --git a/src/Relation.cpp b/src/osm_elements/Relation.cpp
similarity index 85%
rename from src/Relation.cpp
rename to src/osm_elements/Relation.cpp
index 0d2fcd3..d7f2228 100644
--- a/src/Relation.cpp
+++ b/src/osm_elements/Relation.cpp
@@ -21,7 +21,7 @@
 
 #include <boost/lexical_cast.hpp>
 #include <string>
-#include "./Relation.h"
+#include "osm_elements/Relation.h"
 
 namespace osm2pgr {
 
@@ -57,6 +57,21 @@ Relation::add_member(const char **atts) {
     return osm_id;
 }
 
+std::string
+Relation::members_str() const {
+    std::string way_list("");
+    for (const auto &way_ref : m_WayRefs) {
+        way_list += boost::lexical_cast<std::string>(way_ref)
+        /*
+         * currently only adding way
+         */
+            + "=>\"type=>way,role=>TODO\"" + ",";
+    }
+    way_list[way_list.size() -1] = ' ';
+
+    return way_list;
+}
+
 
 }  // end namespace osm2pgr
 
diff --git a/src/Way.cpp b/src/osm_elements/Way.cpp
similarity index 87%
rename from src/Way.cpp
rename to src/osm_elements/Way.cpp
index a4ffa4e..6fa2cf3 100644
--- a/src/Way.cpp
+++ b/src/osm_elements/Way.cpp
@@ -19,7 +19,7 @@
  ***************************************************************************/
 
 
-#include "Way.h"
+#include "osm_elements/Way.h"
 #include "boost/lexical_cast.hpp"
 #include <algorithm>
 #include <string>
@@ -27,9 +27,9 @@
 #include <map>
 #include <vector>
 #include <iostream>
-#include "./OSMDocument.h"
-#include "./osm_tag.h"
-#include "./Node.h"
+#include "osm_elements/OSMDocument.h"
+#include "osm_elements/osm_tag.h"
+#include "osm_elements/Node.h"
 
 
 
@@ -40,13 +40,13 @@ Way::Way(const char **atts) :
     Element(atts),
     m_maxspeed_forward(-1),
     m_maxspeed_backward(-1),
-    m_oneWay("UNKNOWN") { }
-
-
+    m_oneWay("UNKNOWN") { 
+    }
 
 Tag
 Way::add_tag(const Tag &tag) {
     m_tags[tag.key()] = tag.value();
+    implied_oneWay(tag);
     oneWay(tag);
     max_speed(tag);
     return tag;
@@ -54,15 +54,19 @@ Way::add_tag(const Tag &tag) {
 
 
 void
+Way::add_node(int64_t node_id) {
+    m_node_ids.push_back(node_id);
+}
+
+void
 Way::add_node(Node *node) {
     assert(node);
     m_NodeRefs.push_back(node);
 }
 
 
-
 std::string
-Way::geometry_str() const {
+Way::get_geometry() const {
     return geometry_str(m_NodeRefs);
 }
 
@@ -74,7 +78,9 @@ Way::length_str() const {
 
 std::string
 Way::geometry_str(const std::vector<Node*> &nodeRefs) const {
-    std::string geometry("LINESTRING(");
+    if (nodeRefs.size() < 2) return "srid=4326;LINESTRING EMPTY";
+
+    std::string geometry("srid=4326;LINESTRING(");
 
     for (auto it = nodeRefs.begin();
             it != nodeRefs.end();
@@ -150,18 +156,20 @@ Way::split_me() {
 
 std::string
 Way::oneWay() const {
-    return m_oneWay;
+    return static_cast<std::string>(m_oneWay);
 }
 
 void
 Way::oneWay(const Tag &tag) {
     auto key = tag.key();
     auto value = tag.value();
+
     if (key != "oneway") {
-        implied_oneWay(tag);
         return;
     }
 
+    if (m_oneWay != "UNKNOWN") return;
+
     // one way tag
     if ((value == "yes") || value == "true" || value == "1") {
         m_oneWay = "YES";
@@ -196,7 +204,7 @@ Way::implied_oneWay(const Tag &tag) {
             || (key == "highway"
                 && (value == "motorway"
                     || value == "trunk") )) {
-        m_oneWay == "YES";
+        m_oneWay = "YES";
         return;
     }
 
@@ -204,7 +212,7 @@ Way::implied_oneWay(const Tag &tag) {
             && (value == "primary"
                 || value == "secondary"
                 || value == "tertiary")) {
-        m_oneWay == "NO";
+        m_oneWay = "NO";
         return;
     }
 }
@@ -224,7 +232,7 @@ Way::pedestrian(const std::string &key, const std::string &value) {
             || (key == "highway" && value == "cycleway")
             || (key == "highway" && value == "bridleway")
             || (key == "highway" && value == "track")
-            || (key == "sidewak" && value != "no")  )
+            || (key == "sidewalk" && value != "no")  )
         || (key == "foot" && value != "no")  )
             || (key == "highway" && value == "steps") {
                 m_pedestrian = "YES";
@@ -256,7 +264,7 @@ Way::get_kph(const std::string &value) const {
         }
     }
 
-    mph_pos = value.find(" knots");
+    mph_pos = value.find("knots");
     if (mph_pos != std::string::npos) {
         auto newstr = value;
         newstr.erase(mph_pos, std::string::npos);
@@ -284,21 +292,17 @@ void
 Way::max_speed(const Tag &tag) {
     auto key = tag.key();
     auto value = tag.value();
-    if (key == "maxspeed:forward" && m_maxspeed_forward <=0) {
+    if (key == "maxspeed:forward") {
         m_maxspeed_forward = get_kph(value);
         return;
     }
-    if (key == "maxspeed:backward" && m_maxspeed_backward <=0) {
+    if (key == "maxspeed:backward") {
         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);
-        }
+        m_maxspeed_backward = get_kph(value);
+        m_maxspeed_forward = get_kph(value);
         return;
     }
 }
@@ -322,6 +326,18 @@ Way::insert_tags(const std::map<std::string, std::string> &tags) {
     }
 }
 
+std::string
+Way::members_str() const {
+    /* this list comes from the node_ids becuase a node might not be on the file */
+    std::string node_list("");
+    for (const auto &node_id : m_node_ids) {
+        node_list += boost::lexical_cast<std::string>(node_id) + "=>\"type=>nd\",";
+    } 
+    node_list[node_list.size() -1] = ' ';
+
+    return node_list;
+}
+
 
 
 #ifndef NDEBUG
diff --git a/src/osm2pgrouting.cpp b/src/osm_elements/osm2pgrouting.cpp
similarity index 60%
rename from src/osm2pgrouting.cpp
rename to src/osm_elements/osm2pgrouting.cpp
index ecbbd22..ca7250a 100644
--- a/src/osm2pgrouting.cpp
+++ b/src/osm_elements/osm2pgrouting.cpp
@@ -32,11 +32,41 @@
 #include <chrono>
 #endif
 
-#include "./ConfigurationParserCallback.h"
-#include "./OSMDocumentParserCallback.h"
-#include "./OSMDocument.h"
-#include "./Export2DB.h"
-#include "./prog_options.h"
+#include <pqxx/pqxx>
+
+#include "parser/ConfigurationParserCallback.h"
+#include "parser/OSMDocumentParserCallback.h"
+#include "osm_elements/OSMDocument.h"
+#include "database/Export2DB.h"
+#include "utilities/handle_pgpass.h"
+#include "utilities/prog_options.h"
+
+static
+size_t lines_in_file(const std::string file_name) {
+    FILE *in;
+    char buff[512];
+    std::string command = "wc -l  " + file_name;
+
+    if (!(in = popen(command.c_str(), "r"))) {
+        std::cerr << "File not found" << file_name << "\n";
+        exit(1);
+    }
+
+    std::string word;
+    if (fgets(buff, 512, in) != NULL) {
+        word = buff;
+    }
+    pclose(in);
+    std::istringstream iss(word);
+    std::string number;
+    iss >> number;
+    try {
+        return boost::lexical_cast<size_t>(number);
+    } catch (...) {
+        std::cerr << "File not found" << file_name << "\n";
+        exit(1);
+    }
+}
 
 
 int main(int argc, char* argv[]) {
@@ -51,6 +81,7 @@ int main(int argc, char* argv[]) {
     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);
@@ -65,7 +96,7 @@ int main(int argc, char* argv[]) {
         }
 
         if (vm.count("version")) {
-            std::cout << "This is osm2pgrouting Version 2.2\n";
+            std::cout << "This is osm2pgrouting Version 2.3\n";
             return 0;
         }
 
@@ -86,19 +117,70 @@ int main(int argc, char* argv[]) {
 
         auto dataFile(vm["file"].as<string>());
         auto confFile(vm["conf"].as<string>());
-        auto skipnodes(!vm.count("addnodes"));
         auto clean(vm.count("clean"));
+        auto no_index(vm.count("no-index"));
+
+        handle_pgpass(vm);
+        std::string connection_str(
+                    "host=" + vm["host"].as<std::string>()
+                    + " user=" +  vm["username"].as<std::string>()
+                    + " dbname=" + vm["dbname"].as<std::string>()
+                    + " port=" + vm["port"].as<std::string>()
+                    + " password=" + vm["password"].as<std::string>());
+        try {
+            cout << "Testing database connection: "
+                << vm["dbname"].as<std::string>()
+                << endl;
+            pqxx::connection C(connection_str);
+            if (C.is_open()) {
+                cout << "database connection successfull: " << C.dbname() << endl;
+            } else {
+                cout << "Can't open database" << endl;
+                return 1;
+            }
+            C.disconnect ();
+        }catch (const std::exception &e){
+            cerr << e.what() << std::endl;
+            return 1;
+        } 
 
-
+        /* 
+         * preparing the databasse
+         */
         std::cout << "Connecting to the database"  << endl;
-        osm2pgr::Export2DB dbConnection(vm);
+        osm2pgr::Export2DB dbConnection(vm, connection_str);
         if (dbConnection.connect() == 1)
             return 1;
-        if (!dbConnection.has_postGIS()) {
+
+#ifndef NDEBUG
+        dbConnection.install_postGIS();
+#endif
+
+        if (!dbConnection.has_extension("postgis")) {
             std::cout << "ERROR: postGIS not found\n";
+            std::cout << "   HINT: CREATE EXTENSION postGIS\n";
             return 1;
         }
+        if ((vm.count("attributes") || vm.count("tags"))
+                && !dbConnection.has_extension("hstore")) {
+            std::cout << "ERROR: hstore not found\n";
+            std::cout << "   HINT: CREATE EXTENSION hstore\n";
+            return 1;
+        } 
 
+        if (clean) {
+            std::cout << "\nDropping tables..." << endl;
+            dbConnection.dropTables();
+            std::cout << "\nCreating tables..." << endl;
+            dbConnection.createTables();
+        }
+#if 0
+        std::cout << "\nCreating tables..." << endl;
+        dbConnection.createTables();
+#endif
+        /* 
+         * End: preparing the databasse
+         */
 
         std::cout << "Opening configuration file: " << confFile.c_str() << endl;
         osm2pgr::Configuration config;
@@ -109,57 +191,56 @@ int main(int argc, char* argv[]) {
         xml::XMLParser parser;
         int ret = parser.Parse(cCallback, confFile.c_str());
         if (ret != 0) {
-            cout << "Failed to open / parse config file "
+            cout << "Failed to open / parse config file\n"
                 << confFile.c_str()
                 << endl;
             return 1;
         }
+        std::cout << "Exporting configuration ...\n";
+        dbConnection.export_configuration(config.types());
+        std::cout << "  - Done \n";
 
-        size_t total_lines = 100000;
 
-        osm2pgr::OSMDocument document(config, total_lines);
+        std::cout << "Counting lines ...\n";
+        auto total_lines = lines_in_file(dataFile);
+        std::cout << "  - Done \n";
+
+        std::cout << "Opening data file: "
+            << dataFile
+            << "\ttotal lines: "
+            << total_lines
+            << endl;
+        osm2pgr::OSMDocument document(config, vm, dbConnection, total_lines);
         osm2pgr::OSMDocumentParserCallback callback(document);
 
-        std::cout << "    Parsing data (progress line per " << total_lines << " elements)\n" << endl;
+        std::cout << "    Parsing data\n" << endl;
         ret = parser.Parse(callback, dataFile.c_str());
         if (ret != 0) {
             cerr << "Failed to open / parse data file " << dataFile << endl;
             return 1;
         }
         std::cout << "    Finish Parsing data\n" << endl;
-        if (document.nodesErrs()) {
-            std::cerr << "******\nNOTICE:  Found " << document.nodesErrs() << " node references with no <node ... >\n*****";
+        if (document.nodeErrs()) {
+            std::cerr << "******\nNOTICE:  Found " << document.nodeErrs() << " node references with no <node ... >\n*****";
         }
 
         //############# Export2DB
         {
-            if (clean) {
-                std::cout << "\nDropping tables..." << endl;
-                dbConnection.dropTables();
-            }
-
-            std::cout << "\nCreating tables..." << endl;
-            dbConnection.createTables();
 
             std::cout << "Adding auxiliary tables to database..." << endl;
-            if (!skipnodes) {
-                std::cout << "\nExport Nodes ..." << endl;
-                dbConnection.exportNodes(document.nodes());
-            }
-            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);
 
+            if (!no_index) {
+                std::cout << "\nCreating indexes ..." << endl;
+                dbConnection.createFKeys();
+            }
+
+            std::cout << "\nProcessing Points of Interest ..." << endl;
+            dbConnection.process_pois();
 
-            std::cout << "Creating Foreign Keys ..." << endl;
-            dbConnection.createFKeys();
         }
 
 
@@ -190,7 +271,8 @@ int main(int argc, char* argv[]) {
 #endif
 
         std::cout << "#########################" << endl;
-        return 0;
+
+        exit(0);
     }
     catch (exception &e) {
         std::cout << e.what() << endl;
diff --git a/src/osm_elements/osm_element.cpp b/src/osm_elements/osm_element.cpp
new file mode 100644
index 0000000..49fd339
--- /dev/null
+++ b/src/osm_elements/osm_element.cpp
@@ -0,0 +1,233 @@
+/***************************************************************************
+ *   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_elements/osm_tag.h"
+#include "osm_elements/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 = boost::lexical_cast<bool>(value);
+            }
+           m_attributes[name] = value;
+        }
+    }
+
+void 
+Element::tag_config(const Tag &tag) {
+    m_tag_config = tag;
+}
+
+
+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::is_tag_configured() const {
+        return (m_tag_config.key() != "" && m_tag_config.value() != "");
+}
+
+
+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 + ",";
+    }
+    str[str.size()-1] = '\"';
+    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 + ",";
+    }
+    str[str.size()-1] = '\"';
+    return str;
+}
+
+static
+std::string
+addquotes(const std::string str, bool force) {
+    std::string result("");
+
+    for (auto c : str) {
+        if ( c == '"' ) {
+            /*
+             * To avoid problems with json & hstore
+             * all quotes are converted to single quotes
+             */
+            result += "\'\'";
+            continue;
+        } else if ( c == '\\' ) {
+            result += '\\';
+        } else if (c == '\'') {
+            result += '\'';
+        } else if (c == '\n') {
+            result += "\\n";
+            continue;
+        } else if (c == '\r') {
+            result += "\\r";
+            continue;
+        } else if (c == '\t') {
+            result += "\\t";
+            continue;
+        }
+        result += c;
+    }
+    if (!force) {
+        for (auto c : result) {
+            if  (c == ' ' || c == ',' || c == '=' || c == '>' || c == ':') {
+                return std::string("\"") + result + "\"";
+            }
+        }
+        return result;
+    }
+    return std::string("\"") + result + "\"";
+}
+
+
+static
+std::string
+getHstore(const std::map<std::string, std::string> &values) {
+    std::string hstore;
+    if (values.empty()) return std::string();
+
+    for (const auto item : values) {
+        hstore += item.first 
+            + " => "
+            + addquotes(item.second, true)  + ",";
+    }
+    hstore[hstore.size() - 1] = ' ';
+    hstore += "";
+    return hstore;
+}
+
+#if 0
+static
+std::string
+getJSON(const std::map<std::string, std::string> &values) {
+    if (values.empty()) return std::string("{}");
+    std::string json("{");
+    for (const auto item : values) {
+        json += addquotes(item.first, true) 
+            + ":"
+            + addquotes(item.second, true)  + ",";
+    }
+    json[json.size() - 1] = '}';
+    json += "";
+    return json;
+}
+#endif
+
+std::vector<std::string>
+Element::values(const std::vector<std::string> &columns, bool is_hstore) const {
+    std::vector<std::string> values;
+    for (const auto column : columns) {
+        if (column == "osm_id" || column == "tag_id") { 
+            values.push_back(boost::lexical_cast<std::string>(osm_id()));
+            continue;
+        }   
+        if (column == "tag_name") {
+            values.push_back(m_tag_config.key());
+            continue;
+        }
+        if (column == "tag_value") {
+            values.push_back(m_tag_config.value());
+            continue;
+        }
+        if (column == "the_geom") {
+            values.push_back(get_geometry());
+            continue;
+        }
+
+        if (column == "members") {
+            values.push_back(members_str());
+            continue;
+        }
+
+        if (column == "attributes") {
+            values.push_back(getHstore(m_attributes));
+            continue;
+        }   
+        if (column == "tags") {
+            values.push_back(getHstore(m_tags));
+            if (is_hstore) {};
+
+            continue;
+        }   
+        if (has_attribute(column)) {
+            values.push_back(get_attribute(column));
+            continue;
+        }
+        if (has_tag(column)) {
+            values.push_back(get_tag(column));
+            continue;
+        }
+        values.push_back(std::string(""));
+    }
+    return values;
+}
+
+}  // namespace osm2pgr
diff --git a/src/osm_tag.cpp b/src/osm_elements/osm_tag.cpp
similarity index 98%
rename from src/osm_tag.cpp
rename to src/osm_elements/osm_tag.cpp
index 6d7cf55..503ed64 100644
--- a/src/osm_tag.cpp
+++ b/src/osm_elements/osm_tag.cpp
@@ -19,7 +19,7 @@
  ***************************************************************************/
 
 
-#include "./osm_tag.h"
+#include "osm_elements/osm_tag.h"
 #include <string>
 
 namespace osm2pgr {
diff --git a/src/ConfigurationParserCallback.cpp b/src/parser/ConfigurationParserCallback.cpp
similarity index 79%
rename from src/ConfigurationParserCallback.cpp
rename to src/parser/ConfigurationParserCallback.cpp
index 18b47cd..c0d9173 100644
--- a/src/ConfigurationParserCallback.cpp
+++ b/src/parser/ConfigurationParserCallback.cpp
@@ -18,15 +18,13 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
-#include "./ConfigurationParserCallback.h"
+#include "parser/ConfigurationParserCallback.h"
 
 #include <boost/lexical_cast.hpp>
-
 #include <string>
-#include "./OSMDocument.h"
-#include "./Configuration.h"
-#include "./Type.h"
-#include "./Class.h"
+
+#include "osm_elements/OSMDocument.h"
+#include "configuration/configuration.h"
 
 namespace osm2pgr {
 
@@ -36,18 +34,21 @@ namespace osm2pgr {
 void ConfigurationParserCallback::StartElement(
         const char *name,
         const char** atts) {
-    if (strcmp(name, "class") == 0) {
-         m_current->add_class(atts);
-    } else if (strcmp(name, "type") == 0) {
-        m_current = new Type(atts);
+    /* the type is the tag_key */
+    if (strcmp(name, "tag_name") == 0) {
+        m_current = new Tag_key(atts);
+    /* the class is the tag_value */
+    } else if (strcmp(name, "tag_value") == 0) {
+         m_current->add_tag_value(Tag_value(atts));
     } else if (strcmp(name, "configuration") == 0) {
     }
 }
 
 
 void ConfigurationParserCallback::EndElement(const char* name) {
-    if (strcmp(name, "type") == 0) {
-        m_config.AddType(*m_current);
+    /* the type is the tag_key */
+    if (strcmp(name, "tag_name") == 0) {
+        m_config.add_tag_key(*m_current);
         delete m_current;
     }
 }
diff --git a/src/OSMDocumentParserCallback.cpp b/src/parser/OSMDocumentParserCallback.cpp
similarity index 77%
rename from src/OSMDocumentParserCallback.cpp
rename to src/parser/OSMDocumentParserCallback.cpp
index 1c3621c..68df9fb 100644
--- a/src/OSMDocumentParserCallback.cpp
+++ b/src/parser/OSMDocumentParserCallback.cpp
@@ -20,19 +20,19 @@
 
 
 
-#include "./OSMDocumentParserCallback.h"
+#include "parser/OSMDocumentParserCallback.h"
 
 #include <math.h>
 #include <string>
 #include <cassert>
 #include <iostream>
 #include <sstream>
-#include "./OSMDocument.h"
-#include "./print_progress.h"
-#include "./Relation.h"
-#include "./osm_tag.h"
-#include "./Way.h"
-#include "./Node.h"
+#include "osm_elements/OSMDocument.h"
+#include "osm_elements/Relation.h"
+#include "osm_elements/osm_tag.h"
+#include "osm_elements/Way.h"
+#include "osm_elements/Node.h"
+#include "utilities/print_progress.h"
 
 
 namespace osm2pgr {
@@ -56,9 +56,15 @@ namespace osm2pgr {
 
 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;
+    try {
+        if (m_line == 0) return;
+        assert(m_rDocument.lines());
+        if (m_rDocument.lines() == 0) return;
+        if (((++m_line) % (m_rDocument.lines() / 100)) == 0) {
+            print_progress(m_rDocument.lines(), m_line);
+        }
+    } catch(...) {
+        m_line = 1;
     }
 }
 
@@ -81,12 +87,10 @@ OSMDocumentParserCallback::StartElement(
         if (strcmp(name, "node") == 0) {
             last_node = new Node(atts);
         }
-#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));
+            auto tag = last_node->add_tag(Tag(atts));
+            m_rDocument.add_config(last_node, tag);
         }
-#endif
         return;
     }
 
@@ -96,7 +100,7 @@ OSMDocumentParserCallback::StartElement(
         }
         if (strcmp(name, "tag") == 0) {
             auto tag = last_way->add_tag(Tag(atts));
-            m_rDocument.add_config(*last_way, tag);
+            m_rDocument.add_config(last_way, tag);
         }
 
         if (strcmp(name, "nd") == 0) {
@@ -134,55 +138,46 @@ OSMDocumentParserCallback::StartElement(
             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);
-                    }
-                }
-            }
+            auto tag = last_relation->add_tag(Tag(atts));
+            m_rDocument.add_config(last_relation, tag);
         }
     } else if (strcmp(name, "osm") == 0) {
     }
 }
 
 void OSMDocumentParserCallback::EndElement(const char* name) {
+    if (strcmp(name, "osm") == 0) {
+        return;
+    }
     if (strcmp(name, "node") == 0) {
         m_rDocument.AddNode(*last_node);
         delete last_node;
         return;
     }
     if (strcmp(name, "way") == 0) {
-        if (m_rDocument.has_class(last_way->tag_config())) {
-            auto newValue = m_rDocument.class_default_maxspeed(
-                    last_way->tag_config());
+        m_rDocument.AddWay(*last_way);
+        if (m_rDocument.config_has_tag(last_way->tag_config())) {
 
+            auto maxspeed = m_rDocument.maxspeed(last_way->tag_config());
             if (last_way->maxspeed_forward() <= 0) {
-                last_way->maxspeed_forward(newValue);
+                last_way->maxspeed_forward(maxspeed);
             }
             if (last_way->maxspeed_backward() <= 0) {
-                last_way->maxspeed_backward(newValue);
+                last_way->maxspeed_backward(maxspeed);
             }
         }
-
-        m_rDocument.AddWay(*last_way);
         delete last_way;
         return;
 
     } else if (strcmp(name, "relation") == 0) {
-        if (m_rDocument.has_class(last_relation->tag_config())) {
+        if (m_rDocument.config_has_tag(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(
+                    auto newValue = m_rDocument.maxspeed(
                             last_relation->tag_config());
                     if (way_ptr->maxspeed_forward() <= 0) {
                         way_ptr->maxspeed_forward(newValue);
@@ -192,11 +187,12 @@ void OSMDocumentParserCallback::EndElement(const char* name) {
                     }
                 }
             }
-            m_rDocument.AddRelation(*last_relation);
         }
+        m_rDocument.AddRelation(*last_relation);
         delete last_relation;
 
     } else if (strcmp(name, "osm") == 0) {
+        m_rDocument.endOfFile();
         show_progress();
     }
 }
diff --git a/src/XMLParser.cpp b/src/parser/XMLParser.cpp
similarity index 98%
rename from src/XMLParser.cpp
rename to src/parser/XMLParser.cpp
index 1a20f74..5ece1d3 100644
--- a/src/XMLParser.cpp
+++ b/src/parser/XMLParser.cpp
@@ -19,7 +19,7 @@
  ***************************************************************************/
 
 
-#include "./XMLParser.h"
+#include "parser/XMLParser.h"
 
 #include <errno.h>
 #include <string.h>
@@ -74,6 +74,7 @@ int XMLParser::Parse(XMLParserCallback& rCallback, const char* chFileName) {
         fclose(fp);
         ret = 2;    // quit, return = 2 indicating parsing error
         done = 1;
+        return ret;
       }
     } while (!done);
 
diff --git a/src/utilities/handle_pgpass.cpp b/src/utilities/handle_pgpass.cpp
new file mode 100644
index 0000000..009ba7f
--- /dev/null
+++ b/src/utilities/handle_pgpass.cpp
@@ -0,0 +1,94 @@
+/*PGR-GNU*****************************************************************
+
+ Copyright (c) 2017 pgRouting developers
+ Mail: 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 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.
+********************************************************************PGR-GNU*/
+
+
+#include <iostream>
+#include <boost/program_options.hpp>
+#include <sys/stat.h>
+#include <fstream>
+#include <cstdlib>
+#include <string>
+#include <unistd.h>
+
+namespace po = boost::program_options;
+
+void
+handle_pgpass(po::variables_map &vm) {
+
+    if (!vm["password"].as<std::string>().empty()) {
+        /*
+         * nothing to do password is given
+         */
+        return;
+    }
+
+
+
+    std::string file;
+    auto filename(getenv("PGPASSFILE"));
+    if (!filename) {
+#if 0
+        std::cout << "No PGPASSFILE found \n";
+        std::cout << "Looking for .pgpass \n";
+#endif
+        auto homedir(getenv("HOME"));
+        if (!homedir) {
+            std::cout << "No $HOME found \n";
+            return;
+        }
+#if 0
+        std::cout << "home directory" << homedir << "\n";
+#endif
+        file = std::string(homedir) + "/.pgpass";
+    }
+    else {
+        file = filename;
+    }
+    std::ifstream infile(file.c_str());
+    if (!infile.good()) {
+        return;
+    }
+
+
+    std::string host;
+    std::string port;
+    std::string dbase;
+    std::string user;
+    std::string passwd;
+    std::string username = vm["username"].as<std::string>().empty() ?
+        getenv("USER") : vm["username"].as<std::string>();
+    vm.at("username").value() = username;
+    while (std::getline(infile, host, ':')) {
+        std::getline(infile, port, ':');
+        std::getline(infile, dbase, ':');
+        std::getline(infile, user, ':');
+        std::getline(infile, passwd);
+        if ((host == ""  || host == "*" || host == vm["host"].as<std::string>())
+                && (port == "*" || port == vm["port"].as<std::string>())
+                && (dbase == "*" || dbase == vm["dbname"].as<std::string>())
+                && (user == "*" || user == username)
+                && (dbase == "*" || host == vm["dbname"].as<std::string>())) {
+            infile.close();
+            std::cout << passwd << "\n";
+            vm.at("password").value() = passwd;
+            return;
+        }
+    }
+    return;
+}
diff --git a/src/prog_options.cpp b/src/utilities/prog_options.cpp
similarity index 79%
rename from src/prog_options.cpp
rename to src/utilities/prog_options.cpp
index 55c89ad..79446f7 100644
--- a/src/prog_options.cpp
+++ b/src/utilities/prog_options.cpp
@@ -51,13 +51,24 @@ void get_option_description(po::options_description &od_desc) {
         ("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.");
+        ("postgis", "Install postgis if not found.")  // TODO(vicky) remove before realesing
+        ("addnodes", "Import the osm_nodes, osm_ways & osm_relations tables.")
+        ("attributes", "Include attributes information.")
+        ("tags", "Include tag information.")
+        ("chunk", po::value<std::size_t>()->default_value(20000), "Exporting chunk size.")
+        ("clean", "Drop previously created tables.")
+        ("no-index", "Do not create indexes (Use when indexes are already created)");
+#if 0
+        ("addways", "Import the osm_ways table.")
+        ("addrelations", "Import the osm_relations table.")
+        ("fork", "Use fork (works on small files).");
+        ("hstore", "Use hstore for attributes and/or tags. (not indicating will use json)")
+#endif
 
     db_options_od_desc.add_options()
         // database options
         ("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.")
+        ("username,U", po::value<std::string>()->default_value(""), "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.");
@@ -89,7 +100,14 @@ process_command_line(po::variables_map &vm) {
     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("postgis")? "I" : "Don't I") << "nstall postgis if not found\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 << (vm.count("no-index")? "D" : "Don't c") << "reate indexes\n";
+    std::cout << (vm.count("addnodes")? "A" : "Don't a") << "dd OSM nodes\n";
+    std::cout << (vm.count("addways")? "A" : "Don't a") << "dd OSM ways\n";
+    std::cout << (vm.count("addrelations")? "A" : "Don't a") << "dd OSM relations\n";
+#if 0
+    std::cout << (vm.count("fork")? "F" : "Don't f") << "ork\n";
+#endif
     std::cout << "***************************************************\n";
 }
diff --git a/src/utilities/utilities.cpp b/src/utilities/utilities.cpp
new file mode 100644
index 0000000..0514bd4
--- /dev/null
+++ b/src/utilities/utilities.cpp
@@ -0,0 +1,47 @@
+/*PGR-GNU*****************************************************************
+
+ Copyright (c) 2017 pgRouting developers
+ Mail: 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 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.
+********************************************************************PGR-GNU*/
+
+#include <string>
+#include <vector>
+
+
+
+std::string 
+comma_separated(const std::vector<std::string> &columns) {
+    std::string result(" ");
+    for (auto column: columns) {
+        result += column + ",";
+    }                       
+    result[result.size() - 1] = ' '; 
+    return result;
+}
+
+std::string 
+tab_separated(const std::vector<std::string> &columns) {
+    std::string result(" ");
+    for (auto column: columns) {
+        if (column.empty() || column == "") {
+            result += "\\N\t";
+        } else {
+            result += column + "\t";
+        }
+    }                       
+    result[result.size() - 1] = '\n'; 
+    return result;
+}
diff --git a/tools/data/getdata.sh b/tools/data/getdata.sh
index 0dd00e9..c0659de 100644
--- a/tools/data/getdata.sh
+++ b/tools/data/getdata.sh
@@ -12,3 +12,5 @@ wget --progress=dot:mega -O "sampledataSW.osm" "http://www.overpass-api.de/api/x
 BBOX="-122.65,45.4, -122.6,45.45"
 wget --progress=dot:mega -O "small.osm" "http://www.overpass-api.de/api/xapi?*[bbox=${BBOX}][@meta]"
 
+BBOX="4.2878,50.8139,4.5023,50.8926"
+wget --progress=dot:mega -O "brussels.osm" "http://www.overpass-api.de/api/xapi?*[bbox=${BBOX}][@meta]"
diff --git a/tools/doxygen/Doxyfile b/tools/doxygen/Doxyfile
index ec9050e..5fb7f4b 100644
--- a/tools/doxygen/Doxyfile
+++ b/tools/doxygen/Doxyfile
@@ -44,14 +44,14 @@ PROJECT_NUMBER         = 2.1
 # for a project that appears at the top of each page and should give viewer a
 # quick idea about the purpose of the project. Keep the description short.
 
-PROJECT_BRIEF          = "osm2pgrouting provides the tools to import to a SQL geospatial database the routabla data from osm."
+PROJECT_BRIEF          = "osm2pgrouting provides the tools to import to a SQL geospatial database the routable data from osm."
 
 # With the PROJECT_LOGO tag one can specify an logo or icon that is included in
 # the documentation. The maximum height of the logo should not exceed 55 pixels
 # and the maximum width should not exceed 200 pixels. Doxygen will copy the logo
 # to the output directory.
 
-PROJECT_LOGO           = "../../doc/static/images/pgrouting-logo.png"
+PROJECT_LOGO           = "./images/pgrouting-logo.png"
 
 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
 # into which the generated documentation will be written. If a relative path is
@@ -742,7 +742,7 @@ WARN_FORMAT            = "$file:$line: $text"
 # messages should be written. If left blank the output is written to standard
 # error (stderr).
 
-WARN_LOGFILE           =
+WARN_LOGFILE           = "LOG.txt"
 
 #---------------------------------------------------------------------------
 # Configuration options related to the input files
@@ -805,7 +805,7 @@ EXCLUDE_SYMLINKS       = NO
 # Note that the wildcards are matched against the file with absolute path, so to
 # exclude all test directories for example use the pattern */test/*
 
-EXCLUDE_PATTERNS       = */notUsed/*
+EXCLUDE_PATTERNS       = */notUsed/* */tools/* */build/* */fix_typos/*
 
 # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
 # (namespaces, classes, functions, etc.) that should be excluded from the
@@ -842,7 +842,7 @@ EXAMPLE_RECURSIVE      = NO
 # that contain images that are to be included in the documentation (see the
 # \image command).
 
-IMAGE_PATH             = ../../doc/static/images/developers/
+IMAGE_PATH             = ./images
 
 # The INPUT_FILTER tag can be used to specify a program that doxygen should
 # invoke to filter for each input file. Doxygen will invoke the filter program
@@ -2237,7 +2237,7 @@ DOT_PATH               =
 # command).
 # This tag requires that the tag HAVE_DOT is set to YES.
 
-DOTFILE_DIRS           = ../doc/images/
+DOTFILE_DIRS           = ./images
 
 # The MSCFILE_DIRS tag can be used to specify one or more directories that
 # contain msc files that are included in the documentation (see the \mscfile
diff --git a/tools/doxygen/images/pgrouting-logo.png b/tools/doxygen/images/pgrouting-logo.png
new file mode 100644
index 0000000..f65824f
Binary files /dev/null and b/tools/doxygen/images/pgrouting-logo.png differ

-- 
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