diff --git a/include/base_struct.h b/include/base_struct.h
index 0143567389..3d11391de9 100644
--- a/include/base_struct.h
+++ b/include/base_struct.h
@@ -41,6 +41,7 @@
 #include <class_eda_rect.h>
 #include <functional>
 
+
 #if defined(DEBUG)
 #include <iostream>         // needed for Show()
 extern std::ostream& operator <<( std::ostream& out, const wxSize& size );
@@ -86,17 +87,20 @@ class MSG_PANEL_ITEM;
 /**
  * Typedef INSPECTOR
  * is used to inspect and possibly collect the
- * (search) results of Iterating over a list or tree of KICAD_T objects.
+ * (search) results of iterating over a list or tree of KICAD_T objects.
  * Provide an implementation as needed to inspect EDA_ITEMs visited via
- * the EDA_ITEM::Visit() and EDA_ITEM::IterateForward().
+ * EDA_ITEM::Visit() and EDA_ITEM::IterateForward().
  * <p>
- * The lambda function is used within the EDA_ITEM::Iterate() function.
- * It is used primarily for searching, but  not limited to that.  It can also
- * collect or modify the scanned objects.
+ * FYI the std::function may hold a lambda, std::bind, pointer to func, or
+ * ptr to member function, per modern C++. It is used primarily for searching,
+ * but not limited to that.  It can also collect or modify the scanned objects.
+ * 'Capturing' lambdas are particularly convenient because they can use context
+ * and this often means @a aTestData is not used.
  *
  * @param aItem An EDA_ITEM to examine.
  * @param aTestData is arbitrary data needed by the inspector to determine
- *                  if the EDA_ITEM under test meets its match criteria.
+ *  if the EDA_ITEM under test meets its match criteria, and is often NULL
+ *  with the advent of capturing lambdas.
  * @return A #SEARCH_RESULT type #SEARCH_QUIT if the iterator function is to
  *          stop the scan, else #SEARCH_CONTINUE;
  */
diff --git a/include/class_collector.h b/include/class_collector.h
index 173ca7d24b..fd817a445a 100644
--- a/include/class_collector.h
+++ b/include/class_collector.h
@@ -55,7 +55,8 @@ class EDA_ITEM;
 class COLLECTOR
 {
 protected:
-    INSPECTOR_FUNC  m_inspector;
+    /// a class common bridge into the polymorphic Inspect()
+    INSPECTOR_FUNC m_inspector;
 
     /// Which object types to scan
     const KICAD_T* m_ScanTypes;
@@ -75,7 +76,7 @@ protected:
 public:
     COLLECTOR() :
         // Inspect() is virtual so calling it from a class common inspector preserves polymorphism.
-        m_inspector( [=] ( EDA_ITEM* aItem, void* aTestData ) { return Inspect( aItem, aTestData ); } )
+        m_inspector( [=] ( EDA_ITEM* aItem, void* aTestData ) { return this->Inspect( aItem, aTestData ); } )
     {
         m_ScanTypes = 0;
         m_TimeAtCollection = 0;
diff --git a/include/core/typeinfo.h b/include/core/typeinfo.h
index b6f1ce626c..1c4c4e597f 100644
--- a/include/core/typeinfo.h
+++ b/include/core/typeinfo.h
@@ -26,10 +26,63 @@
 #ifndef __KICAD_TYPEINFO_H
 #define __KICAD_TYPEINFO_H
 
+
+#ifndef SWIG
 #include <cstdio>
 
+template<typename T>
+struct remove_pointer
+{
+    typedef T type;
+};
+
+template<typename T>
+struct remove_pointer<T*>
+{
+    typedef typename remove_pointer<T>::type type;
+};
+
+/**
+ * Function IsA()
+ *
+ * Checks if the type of aObject is T.
+ * @param aObject object for type check
+ * @return true, if aObject type equals T.
+ */
+template <class T, class I>
+bool IsA( const I* aObject )
+{
+    return aObject && remove_pointer<T>::type::ClassOf( aObject );
+}
+
+template <class T, class I>
+bool IsA( const I& aObject )
+{
+    return remove_pointer<T>::type::ClassOf( &aObject );
+}
+
+/**
+ * Function dyn_cast()
+ *
+ * A lightweight dynamic downcast. Casts aObject to type Casted*.
+ * Uses EDA_ITEM::Type() and EDA_ITEM::ClassOf() to check if type matches.
+ * @param aObject object to be casted
+ * @return down-casted object or NULL if type doesn't match Casted.
+ */
+template<class Casted, class From>
+Casted dyn_cast( From aObject )
+{
+    if( remove_pointer<Casted>::type::ClassOf ( aObject ) )
+        return static_cast<Casted>( aObject );
+
+    return NULL;
+}
+
 class EDA_ITEM;
 
+#endif  // SWIG
+
+
 /**
  * Enum KICAD_T
  * is the set of class identification values, stored in EDA_ITEM::m_StructType
@@ -129,52 +182,4 @@ enum KICAD_T
     MAX_STRUCT_TYPE_ID
 };
 
-template<typename T>
-struct remove_pointer
-{
-    typedef T type;
-};
-
-template<typename T>
-struct remove_pointer<T*>
-{
-    typedef typename remove_pointer<T>::type type;
-};
-
-/**
- * Function IsA()
- *
- * Checks if the type of aObject is T.
- * @param aObject object for type check
- * @return true, if aObject type equals T.
- */
-template <class T, class I>
-bool IsA( const I* aObject )
-{
-    return aObject && remove_pointer<T>::type::ClassOf( aObject );
-}
-
-template <class T, class I>
-bool IsA( const I& aObject )
-{
-    return remove_pointer<T>::type::ClassOf( &aObject );
-}
-
-/**
- * Function dyn_cast()
- *
- * A lightweight dynamic downcast. Casts aObject to type Casted*.
- * Uses EDA_ITEM::Type() and EDA_ITEM::ClassOf() to check if type matches.
- * @param aObject object to be casted
- * @return down-casted object or NULL if type doesn't match Casted.
- */
-template<class Casted, class From>
-Casted dyn_cast( From aObject )
-{
-    if( remove_pointer<Casted>::type::ClassOf ( aObject ) )
-        return static_cast<Casted>( aObject );
-
-    return NULL;
-}
-
 #endif // __KICAD_TYPEINFO_H
diff --git a/include/hashtables.h b/include/hashtables.h
index 7a625bce23..99108c637c 100644
--- a/include/hashtables.h
+++ b/include/hashtables.h
@@ -28,32 +28,10 @@
 #include <base_struct.h>
 #include <wx/string.h>
 
-// Three strategies for providing a portable hashtable are given.
-// C++, boost, and wx, in that order.  C++ solution is no good for mingw.
-// So boost seems best for all platforms.
+// Two competing strategies for providing portable hashtables are given:
+// std C++ and boost.
 
-
-#if 0   // C++ std::unordered_map, maybe in the future
-
-#include <unordered_map>
-
-
-/// Map a C string to an integer.  Used in DSNLEXER.
-typedef std::unordered_map< std::string, int >          KEYWORD_MAP;
-
-/// Map a C string to an EDA_RECT.
-/// The key is the classname of the derived wxformbuilder dialog.
-typedef std::unordered_map< std::string, EDA_RECT >     RECT_MAP;
-
-
-#elif 1     // boost::unordered_map
-
-// fix a compile bug at line 97 of boost/detail/container_fwd.hpp
-#define BOOST_DETAIL_TEST_FORCE_CONTAINER_FWD
-
-#include <boost/unordered_map.hpp>
-
-// see http://www.boost.org/doc/libs/1_49_0/doc/html/boost/unordered_map.html
+// First some utility classes and functions common to both strategies..
 
 /// Equality test for "const char*" type used in very specialized KEYWORD_MAP below
 struct iequal_to : std::binary_function< const char*, const char*, bool >
@@ -117,6 +95,57 @@ struct WXSTRING_HASH : std::unary_function<wxString, std::size_t>
 };
 
 
+class NETINFO_ITEM;
+
+
+#if 1   // C++ std::unordered_map, trying it now
+
+#include <unordered_map>
+
+
+#ifdef SWIG
+/// Declare a std::unordered_map and also the swig %template in unison
+#define DECL_HASH_FOR_SWIG(TypeName, KeyType, ValueType) namespace std { %template(TypeName) unordered_map<KeyType, ValueType>; } typedef std::unordered_map<KeyType, ValueType> TypeName;
+#else
+/// Declare a std::unordered_map but no swig %template
+#define DECL_HASH_FOR_SWIG(TypeName, KeyType, ValueType) typedef std::unordered_map<KeyType, ValueType> TypeName;
+#endif
+
+
+
+/**
+ * Type KEYWORD_MAP
+ * is a hashtable made of a const char* and an int.  Note that use of this
+ * type outside very specific circumstances is foolish since there is no storage
+ * provided for the actual C string itself.  This type assumes use with type KEYWORD
+ * that is created by CMake and that table creates *constant* storage for C strings
+ * (and pointers to those C strings).  Here we are only interested in the C strings
+ * themselves and only the pointers are duplicated within the hashtable.
+ * If the strings were not constant and fixed, this type would not work.
+ * Also note that normally a hashtable (i.e. unordered_map) using a const char* key
+ * would simply compare the 32 bit or 64 bit pointers themselves, rather than
+ * the C strings which they are known to point to in this context.
+ * I force the latter behavior by supplying both "hash" and "equality" overloads
+ * to the hashtable (unordered_map) template.
+ * @author Dick Hollenbeck
+ */
+typedef std::unordered_map< const char*, int, fnv_1a, iequal_to >   KEYWORD_MAP;
+
+/// Map a C string to an EDA_RECT.
+/// The key is the classname of the derived wxformbuilder dialog.
+typedef std::unordered_map< std::string, EDA_RECT >     RECT_MAP;
+
+
+#elif 1     // boost::unordered_map
+
+// fix a compile bug at line 97 of boost/detail/container_fwd.hpp
+#define BOOST_DETAIL_TEST_FORCE_CONTAINER_FWD
+
+#include <boost/unordered_map.hpp>
+
+// see http://www.boost.org/doc/libs/1_49_0/doc/html/boost/unordered_map.html
+
+
 /**
  * Type KEYWORD_MAP
  * is a hashtable made of a const char* and an int.  Note that use of this
@@ -140,6 +169,9 @@ typedef boost::unordered_map< const char*, int, fnv_1a, iequal_to >     KEYWORD_
 /// The key is the classname of the derived wxformbuilder dialog.
 typedef boost::unordered_map< std::string, EDA_RECT >  RECT_MAP;
 
+typedef boost::unordered_map< const wxString, NETINFO_ITEM*, WXSTRING_HASH > NETNAMES_MAP;
+typedef boost::unordered_map< const int, NETINFO_ITEM* > NETCODES_MAP;
+
 #endif
 
 #endif // HASHTABLES_H_
diff --git a/include/macros.h b/include/macros.h
index 95bcb04466..c93863d960 100644
--- a/include/macros.h
+++ b/include/macros.h
@@ -24,13 +24,16 @@
 
 /**
  * @file macros.h
- * @brief This file contains miscellaneous helper definitions and functions.
+ * @brief This file contains miscellaneous commonly used macros and functions.
  */
 
 #ifndef MACROS_H
 #define MACROS_H
 
 #include <wx/wx.h>
+#include <vector>
+#include <map>
+
 
 /**
  * Macro TO_UTF8
@@ -116,4 +119,15 @@ template <typename T> inline const T& Clamp( const T& lower, const T& value, con
 }
 
 
-#endif /* ifdef MACRO_H */
+#ifdef SWIG
+/// Declare a std::vector and also the swig %template in unison
+#define DECL_VEC_FOR_SWIG(TypeName, MemberType) namespace std { %template(TypeName) vector<MemberType>; } typedef std::vector<MemberType> TypeName;
+#define DECL_MAP_FOR_SWIG(TypeName, KeyType, ValueType) namespace std { %template(TypeName) map<KeyType, ValueType>; } typedef std::map<KeyType, ValueType> TypeName;
+#else
+/// Declare a std::vector but no swig %template
+#define DECL_VEC_FOR_SWIG(TypeName, MemberType) typedef std::vector<MemberType> TypeName;
+#define DECL_MAP_FOR_SWIG(TypeName, KeyType, ValueType) typedef std::map<KeyType, ValueType> TypeName;
+#endif
+
+
+#endif // MACROS_H
diff --git a/include/utf8.h b/include/utf8.h
index 41137d83f9..f654f862d3 100644
--- a/include/utf8.h
+++ b/include/utf8.h
@@ -126,6 +126,7 @@ public:
      */
     static int uni_forward( const unsigned char* aSequence, unsigned* aResult = NULL );
 
+#ifndef SWIG
     /**
      * class uni_iter
      * is a non-muting iterator that walks through unicode code points in the UTF8 encoded
@@ -225,6 +226,7 @@ public:
     {
         return uni_iter( data() + size() );
     }
+#endif  // SWIG
 };
 
 #endif // UTF8_H_
diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp
index 94157be4ab..3fcf32bb2c 100644
--- a/pcbnew/class_board.cpp
+++ b/pcbnew/class_board.cpp
@@ -176,7 +176,7 @@ void BOARD::Move( const wxPoint& aMoveVector )        // overload
 }
 
 
-void BOARD::chainMarkedSegments( wxPoint aPosition, const LSET& aLayerSet, TRACK_PTRS* aList )
+void BOARD::chainMarkedSegments( wxPoint aPosition, const LSET& aLayerSet, TRACKS* aList )
 {
     LSET    layer_set = aLayerSet;
 
@@ -1608,7 +1608,7 @@ TRACK* BOARD::GetVisibleTrack( TRACK* aStartingTrace, const wxPoint& aPosition,
 
 
 #if defined(DEBUG) && 0
-static void dump_tracks( const char* aName, const TRACK_PTRS& aList )
+static void dump_tracks( const char* aName, const TRACKS& aList )
 {
     printf( "%s: count=%zd\n", aName, aList.size() );
 
@@ -1634,7 +1634,7 @@ TRACK* BOARD::MarkTrace( TRACK*  aTrace, int* aCount,
                          double* aTraceLength, double* aPadToDieLength,
                          bool    aReorder )
 {
-    TRACK_PTRS trackList;
+    TRACKS trackList;
 
     if( aCount )
         *aCount = 0;
@@ -1704,8 +1704,8 @@ TRACK* BOARD::MarkTrace( TRACK*  aTrace, int* aCount,
     }
     else    // mark the chain using both ends of the initial segment
     {
-        TRACK_PTRS  from_start;
-        TRACK_PTRS  from_end;
+        TRACKS  from_start;
+        TRACKS  from_end;
 
         chainMarkedSegments( aTrace->GetStart(), layer_set, &from_start );
         chainMarkedSegments( aTrace->GetEnd(),   layer_set, &from_end );
diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h
index 4e4c97c688..452daf6516 100644
--- a/pcbnew/class_board.h
+++ b/pcbnew/class_board.h
@@ -59,9 +59,6 @@ class REPORTER;
 class RN_DATA;
 class SHAPE_POLY_SET;
 
-// non-owning container of item candidates when searching for items on the same track.
-typedef std::vector< TRACK* >   TRACK_PTRS;
-
 
 /**
  * Enum LAYER_T
@@ -156,6 +153,11 @@ protected:
 };
 
 
+DECL_VEC_FOR_SWIG(MARKERS, MARKER_PCB*)
+DECL_VEC_FOR_SWIG(ZONE_CONTAINERS, ZONE_CONTAINER*)
+DECL_VEC_FOR_SWIG(TRACKS, TRACK*)
+
+
 /**
  * Class BOARD
  * holds information pertinent to a Pcbnew printed circuit board.
@@ -168,15 +170,9 @@ private:
     /// the board filename
     wxString                m_fileName;
 
-    // @todo: switch to boost:ptr_vector, and change ~BOARD()
-    typedef std::vector<MARKER_PCB*> MARKERS;
-
     /// MARKER_PCBs for clearance problems, owned by pointer.
     MARKERS                 m_markers;
 
-    // @todo: switch to boost::ptr_vector, and change ~BOARD()
-    typedef std::vector<ZONE_CONTAINER*> ZONE_CONTAINERS;
-
     /// edge zone descriptors, owned by pointer.
     ZONE_CONTAINERS         m_ZoneDescriptorList;
 
@@ -214,7 +210,7 @@ private:
      * @param aLayerSet The allowed layers for segments to search.
      * @param aList The track list to fill with points of flagged segments.
      */
-    void chainMarkedSegments( wxPoint aPosition, const LSET& aLayerSet, TRACK_PTRS* aList );
+    void chainMarkedSegments( wxPoint aPosition, const LSET& aLayerSet, TRACKS* aList );
 
 public:
     static inline bool ClassOf( const EDA_ITEM* aItem )
@@ -778,15 +774,12 @@ public:
 
     /**
      * Function GetPads
-     * returns a list of all the pads by value.  The returned list is not
+     * returns a reference to a list of all the pads.  The returned list is not
      * sorted and contains pointers to PADS, but those pointers do not convey
      * ownership of the respective PADs.
-     * @return std::vector<D_PAD*> - a full list of pads
+     * @return D_PADS - a full list of pads
      */
-    std::vector<D_PAD*> GetPads()
-    {
-        return m_NetInfo.m_PadsFullList;
-    }
+    const D_PADS& GetPads()     { return m_NetInfo.m_PadsFullList; }
 
     void BuildListOfNets()
     {
diff --git a/pcbnew/class_netclass.cpp b/pcbnew/class_netclass.cpp
index 46bc606f3b..858175b16c 100644
--- a/pcbnew/class_netclass.cpp
+++ b/pcbnew/class_netclass.cpp
@@ -119,7 +119,7 @@ bool NETCLASSES::Add( NETCLASSPTR aNetClass )
 
 NETCLASSPTR NETCLASSES::Remove( const wxString& aNetName )
 {
-    NETCLASSMAP::iterator found = m_NetClasses.find( aNetName );
+    NETCLASS_MAP::iterator found = m_NetClasses.find( aNetName );
 
     if( found != m_NetClasses.end() )
     {
@@ -137,7 +137,7 @@ NETCLASSPTR NETCLASSES::Find( const wxString& aName ) const
     if( aName == NETCLASS::Default )
         return m_Default;
 
-    NETCLASSMAP::const_iterator found = m_NetClasses.find( aName );
+    NETCLASS_MAP::const_iterator found = m_NetClasses.find( aName );
 
     if( found == m_NetClasses.end() )
         return NETCLASSPTR();
diff --git a/pcbnew/class_netclass.h b/pcbnew/class_netclass.h
index 658f182f8b..3a4c206601 100644
--- a/pcbnew/class_netclass.h
+++ b/pcbnew/class_netclass.h
@@ -34,6 +34,7 @@
 #include <set>
 #include <map>
 
+#include <macros.h>
 #include <wx/string.h>
 
 #include <richio.h>
@@ -207,7 +208,14 @@ public:
 #endif
 };
 
+
 typedef std::shared_ptr<NETCLASS> NETCLASSPTR;
+#ifdef SWIG
+%shared_ptr( NETCLASSPTR );
+#endif
+
+DECL_MAP_FOR_SWIG( NETCLASS_MAP, wxString, NETCLASSPTR );
+
 
 /**
  * Class NETCLASSES
@@ -218,10 +226,9 @@ typedef std::shared_ptr<NETCLASS> NETCLASSPTR;
 class NETCLASSES
 {
 private:
-    typedef std::map<wxString, NETCLASSPTR> NETCLASSMAP;
 
     /// all the NETCLASSes except the default one.
-    NETCLASSMAP             m_NetClasses;
+    NETCLASS_MAP             m_NetClasses;
 
     /// the default NETCLASS.
     NETCLASSPTR             m_Default;
@@ -239,11 +246,11 @@ public:
         m_NetClasses.clear();
     }
 
-    typedef NETCLASSMAP::iterator iterator;
+    typedef NETCLASS_MAP::iterator iterator;
     iterator begin() { return m_NetClasses.begin(); }
     iterator end()   { return m_NetClasses.end(); }
 
-    typedef NETCLASSMAP::const_iterator const_iterator;
+    typedef NETCLASS_MAP::const_iterator const_iterator;
     const_iterator begin() const { return m_NetClasses.begin(); }
     const_iterator end()   const { return m_NetClasses.end(); }
 
diff --git a/pcbnew/class_netinfo.h b/pcbnew/class_netinfo.h
index b4d76a0cb4..e179fb694a 100644
--- a/pcbnew/class_netinfo.h
+++ b/pcbnew/class_netinfo.h
@@ -30,15 +30,14 @@
  *  Classes to handle info on nets
  */
 
-#ifndef __CLASSES_NETINFO__
-#define __CLASSES_NETINFO__
-
+#ifndef CLASS_NETINFO_
+#define CLASS_NETINFO_
 
+#include <macros.h>
 #include <gr_basic.h>
 #include <class_netclass.h>
 #include <class_board_item.h>
-#include <boost/unordered_map.hpp>
-#include <hashtables.h>
+
 
 
 class wxDC;
@@ -46,7 +45,6 @@ class wxPoint;
 class LINE_READER;
 class EDA_DRAW_PANEL;
 class EDA_DRAW_FRAME;
-class NETINFO_ITEM;
 class D_PAD;
 class BOARD;
 class BOARD_ITEM;
@@ -117,363 +115,7 @@ public:
 };
 
 
-class NETINFO_MAPPING
-{
-public:
-    NETINFO_MAPPING()
-    {
-        m_board = NULL;
-    }
-
-
-    /**
-     * Function SetBoard
-     * Sets a BOARD object that is used to prepare the net code map.
-     */
-    void SetBoard( const BOARD* aBoard )
-    {
-        m_board = aBoard;
-        Update();
-    }
-
-    /**
-     * Function Update
-     * Prepares a mapping for net codes so they can be saved as consecutive numbers.
-     * To retrieve a mapped net code, use translateNet() function after calling this.
-     */
-    void Update();
-
-    /**
-     * Function Translate
-     * Translates net number according to the map prepared by Update() function. It
-     * allows to have items stored with consecutive net codes.
-     * @param aNetCode is an old net code.
-     * @return Net code that follows the mapping.
-     */
-    int Translate( int aNetCode ) const;
-
-#ifndef SWIG
-    ///> Wrapper class, so you can iterate through NETINFO_ITEM*s, not
-    ///> std::pair<int/wxString, NETINFO_ITEM*>
-    class iterator
-    {
-    public:
-        iterator( std::map<int, int>::const_iterator aIter, const NETINFO_MAPPING* aMapping ) :
-            m_iterator( aIter ), m_mapping( aMapping )
-        {
-        }
-
-        /// pre-increment operator
-        const iterator& operator++()
-        {
-            ++m_iterator;
-
-            return *this;
-        }
-
-        /// post-increment operator
-        iterator operator++( int )
-        {
-            iterator ret = *this;
-            ++m_iterator;
-
-            return ret;
-        }
-
-        NETINFO_ITEM* operator*() const;
-
-        NETINFO_ITEM* operator->() const;
-
-        bool operator!=( const iterator& aOther ) const
-        {
-            return m_iterator != aOther.m_iterator;
-        }
-
-        bool operator==( const iterator& aOther ) const
-        {
-            return m_iterator == aOther.m_iterator;
-        }
-
-    private:
-        std::map<int, int>::const_iterator m_iterator;
-        const NETINFO_MAPPING* m_mapping;
-    };
-
-    /**
-     * Function begin()
-     * Returns iterator to the first entry in the mapping.
-     * NOTE: The entry is a pointer to the original NETINFO_ITEM object, this it contains
-     * not mapped net code.
-     */
-    iterator begin() const
-    {
-        return iterator( m_netMapping.begin(), this );
-    }
-
-    /**
-     * Function end()
-     * Returns iterator to the last entry in the mapping.
-     * NOTE: The entry is a pointer to the original NETINFO_ITEM object, this it contains
-     * not mapped net code.
-     */
-    iterator end() const
-    {
-        return iterator( m_netMapping.end(), this );
-    }
-#endif
-
-    /**
-     * Function GetSize
-     * @return Number of mapped nets (i.e. not empty nets for a given BOARD object).
-     */
-    int GetSize() const
-    {
-        return m_netMapping.size();
-    }
-
-private:
-    ///> Board for which mapping is prepared
-    const BOARD* m_board;
-
-    ///> Map that allows saving net codes with consecutive numbers (for compatibility reasons)
-    std::map<int, int> m_netMapping;
-};
-
-
-/**
- * Class NETINFO_LIST
- * is a container class for NETINFO_ITEM elements, which are the nets.  That makes
- * this class a container for the nets.
- */
-class NETINFO_LIST
-{
-    friend class BOARD;
-
-public:
-    NETINFO_LIST( BOARD* aParent );
-    ~NETINFO_LIST();
-
-    /**
-     * Function GetItem
-     * @param aNetCode = netcode to identify a given NETINFO_ITEM
-     * @return NETINFO_ITEM* - by \a aNetCode, or NULL if not found
-     */
-    NETINFO_ITEM* GetNetItem( int aNetCode ) const
-    {
-        NETCODES_MAP::const_iterator result = m_netCodes.find( aNetCode );
-
-        if( result != m_netCodes.end() )
-            return (*result).second;
-
-        return NULL;
-    }
-
-    /**
-     * Function GetItem
-     * @param aNetName = net name to identify a given NETINFO_ITEM
-     * @return NETINFO_ITEM* - by \a aNetName, or NULL if not found
-     */
-    NETINFO_ITEM* GetNetItem( const wxString& aNetName ) const
-    {
-        NETNAMES_MAP::const_iterator result = m_netNames.find( aNetName );
-
-        if( result != m_netNames.end() )
-            return (*result).second;
-
-        return NULL;
-    }
-
-    /**
-     * Function GetNetCount
-     * @return the number of nets ( always >= 1 )
-     * because the first net is the "not connected" net and always exists
-     */
-    unsigned GetNetCount() const { return m_netNames.size(); }
-
-    /**
-     * Function AppendNet
-     * adds \a aNewElement to the end of the net list. Negative net code means it is going to be
-     * auto-assigned.
-     */
-    void AppendNet( NETINFO_ITEM* aNewElement );
-
-    /**
-     * Function RemoveNet
-     * Removes a new from the net list.
-     */
-    void RemoveNet( NETINFO_ITEM* aNet );
-    /**
-     * Function GetPadCount
-     * @return the number of pads in board
-     */
-    unsigned GetPadCount() const  { return m_PadsFullList.size(); }
-
-    /**
-     * Function GetPads
-     * returns a list of all the pads (so long as buildPadsFullList() has
-     * been recently called).  Returned list contains non-owning pointers.
-     * @return std::vector<D_PAD*>& - a full list of pads
-    std::vector<D_PAD*>& GetPads()
-    {
-        return m_PadsFullList;
-    }
-     */
-
-    /**
-     * Function GetPad
-     * @return the pad idx from m_PadsFullList
-     */
-    D_PAD* GetPad( unsigned aIdx ) const
-    {
-        if( aIdx < m_PadsFullList.size() )
-            return m_PadsFullList[aIdx];
-        else
-            return NULL;
-    }
-
-    bool DeletePad( D_PAD* aPad )
-    {
-        std::vector<D_PAD*>::iterator it  = m_PadsFullList.begin();
-        std::vector<D_PAD*>::iterator end = m_PadsFullList.end();
-
-        for( ; it != end;  ++it )
-        {
-            if( *it == aPad )
-            {
-                m_PadsFullList.erase( it );
-                return true;
-            }
-        }
-        return false;
-    }
-
-    ///> Constant that holds the "unconnected net" number (typically 0)
-    ///> all items "connected" to this net are actually not connected items
-    static const int UNCONNECTED;
-
-    ///> Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED
-    ///> (typically -1) when calling SetNetCode od board connected items
-    static const int ORPHANED;
-
-    ///> NETINFO_ITEM meaning that there was no net assigned for an item, as there was no
-    ///> board storing net list available.
-    static NETINFO_ITEM ORPHANED_ITEM;
-
-#if defined(DEBUG)
-    void Show() const;
-#endif
-
-    typedef boost::unordered_map<const wxString, NETINFO_ITEM*, WXSTRING_HASH> NETNAMES_MAP;
-    typedef boost::unordered_map<const int, NETINFO_ITEM*> NETCODES_MAP;
-
-#ifndef SWIG
-    ///> Wrapper class, so you can iterate through NETINFO_ITEM*s, not
-    ///> std::pair<int/wxString, NETINFO_ITEM*>
-    class iterator
-    {
-    public:
-        iterator( NETNAMES_MAP::const_iterator aIter ) : m_iterator( aIter )
-        {
-        }
-
-        /// pre-increment operator
-        const iterator& operator++()
-        {
-            ++m_iterator;
-
-            return *this;
-        }
-
-        /// post-increment operator
-        iterator operator++( int )
-        {
-            iterator ret = *this;
-            ++m_iterator;
-
-            return ret;
-        }
-
-        NETINFO_ITEM* operator*() const
-        {
-            return m_iterator->second;
-        }
-
-        NETINFO_ITEM* operator->() const
-        {
-            return m_iterator->second;
-        }
-
-        bool operator!=( const iterator& aOther ) const
-        {
-            return m_iterator != aOther.m_iterator;
-        }
-
-        bool operator==( const iterator& aOther ) const
-        {
-            return m_iterator == aOther.m_iterator;
-        }
-
-    private:
-        NETNAMES_MAP::const_iterator m_iterator;
-    };
-
-    iterator begin() const
-    {
-        return iterator( m_netNames.begin() );
-    }
-
-    iterator end() const
-    {
-        return iterator( m_netNames.end() );
-    }
-#endif
-
-    BOARD* GetParent() const
-    {
-        return m_Parent;
-    }
-
-private:
-    /**
-     * Function clear
-     * deletes the list of nets (and free memory)
-     */
-    void clear();
-
-    /**
-     * Function buildListOfNets
-     * builds or rebuilds the list of NETINFO_ITEMs
-     * The list is sorted by names.
-     */
-    void buildListOfNets();
-
-    /**
-     * Function buildPadsFullList
-     * creates the pad list, and initializes:
-     *   m_Pads (list of pads)
-     * set m_Status_Pcb = LISTE_PAD_OK;
-     * and clear for all pads in list the m_SubRatsnest member;
-     * clear m_Pcb->m_FullRatsnest
-     */
-    void buildPadsFullList();
-
-    /**
-     * Function getFreeNetCode
-     * returns the first available net code that is not used by any other net.
-     */
-    int getFreeNetCode();
-
-    BOARD* m_Parent;
-
-    NETNAMES_MAP m_netNames;                    ///< map for a fast look up by net names
-    NETCODES_MAP m_netCodes;                    ///< map for a fast look up by net codes
-
-    std::vector<D_PAD*> m_PadsFullList;         ///< contains all pads, sorted by pad's netname.
-                                                ///< can be used in ratsnest calculations.
-
-    int m_newNetCode;                           ///< possible value for new net code assignment
-};
-
+DECL_VEC_FOR_SWIG( D_PADS, D_PAD* )
 
 /**
  * Class NETINFO_ITEM
@@ -496,10 +138,11 @@ private:
                                 // item of the net classes list
     NETCLASSPTR m_NetClass;
 
-    BOARD* m_parent;            ///< The parent board the net belongs to.
+    BOARD*  m_parent;           ///< The parent board the net belongs to.
 
 public:
-    std::vector<D_PAD*> m_PadInNetList;    ///< List of pads connected to this net
+
+    D_PADS  m_PadInNetList;     ///< List of pads connected to this net
 
     unsigned m_RatsnestStartIdx;       /* Starting point of ratsnests of this
                                         * net (included) in a general buffer of
@@ -705,7 +348,340 @@ public:
     {
         return m_parent;
     }
+};
 
+
+#ifndef SWIG
+
+class NETINFO_MAPPING
+{
+public:
+    NETINFO_MAPPING()
+    {
+        m_board = NULL;
+    }
+
+
+    /**
+     * Function SetBoard
+     * Sets a BOARD object that is used to prepare the net code map.
+     */
+    void SetBoard( const BOARD* aBoard )
+    {
+        m_board = aBoard;
+        Update();
+    }
+
+    /**
+     * Function Update
+     * Prepares a mapping for net codes so they can be saved as consecutive numbers.
+     * To retrieve a mapped net code, use translateNet() function after calling this.
+     */
+    void Update();
+
+    /**
+     * Function Translate
+     * Translates net number according to the map prepared by Update() function. It
+     * allows to have items stored with consecutive net codes.
+     * @param aNetCode is an old net code.
+     * @return Net code that follows the mapping.
+     */
+    int Translate( int aNetCode ) const;
+
+#ifndef SWIG
+    ///> Wrapper class, so you can iterate through NETINFO_ITEM*s, not
+    ///> std::pair<int/wxString, NETINFO_ITEM*>
+    class iterator
+    {
+    public:
+        iterator( std::map<int, int>::const_iterator aIter, const NETINFO_MAPPING* aMapping ) :
+            m_iterator( aIter ), m_mapping( aMapping )
+        {
+        }
+
+        /// pre-increment operator
+        const iterator& operator++()
+        {
+            ++m_iterator;
+
+            return *this;
+        }
+
+        /// post-increment operator
+        iterator operator++( int )
+        {
+            iterator ret = *this;
+            ++m_iterator;
+
+            return ret;
+        }
+
+        NETINFO_ITEM* operator*() const;
+
+        NETINFO_ITEM* operator->() const;
+
+        bool operator!=( const iterator& aOther ) const
+        {
+            return m_iterator != aOther.m_iterator;
+        }
+
+        bool operator==( const iterator& aOther ) const
+        {
+            return m_iterator == aOther.m_iterator;
+        }
+
+    private:
+        std::map<int, int>::const_iterator m_iterator;
+        const NETINFO_MAPPING* m_mapping;
+    };
+
+    /**
+     * Function begin()
+     * Returns iterator to the first entry in the mapping.
+     * NOTE: The entry is a pointer to the original NETINFO_ITEM object, this it contains
+     * not mapped net code.
+     */
+    iterator begin() const
+    {
+        return iterator( m_netMapping.begin(), this );
+    }
+
+    /**
+     * Function end()
+     * Returns iterator to the last entry in the mapping.
+     * NOTE: The entry is a pointer to the original NETINFO_ITEM object, this it contains
+     * not mapped net code.
+     */
+    iterator end() const
+    {
+        return iterator( m_netMapping.end(), this );
+    }
+#endif
+
+    /**
+     * Function GetSize
+     * @return Number of mapped nets (i.e. not empty nets for a given BOARD object).
+     */
+    int GetSize() const
+    {
+        return m_netMapping.size();
+    }
+
+private:
+    ///> Board for which mapping is prepared
+    const BOARD* m_board;
+
+    ///> Map that allows saving net codes with consecutive numbers (for compatibility reasons)
+    std::map<int, int> m_netMapping;
+};
+
+#endif  // SWIG
+
+
+#if 0
+// waiting for swig to support std::unordered_map, see
+// http://www.swig.org/Doc3.0/CPlusPlus11.html
+// section 7.3.3
+#include <hashtables.h>
+DECL_HASH_FOR_SWIG( NETNAMES_MAP, wxString,  NETINFO_ITEM* )
+DECL_HASH_FOR_SWIG( NETCODES_MAP, int,       NETINFO_ITEM* )
+#else
+// use std::map for now
+DECL_MAP_FOR_SWIG( NETNAMES_MAP, wxString,  NETINFO_ITEM* )
+DECL_MAP_FOR_SWIG( NETCODES_MAP, int,       NETINFO_ITEM* )
+#endif
+
+/**
+ * Class NETINFO_LIST
+ * is a container class for NETINFO_ITEM elements, which are the nets.  That makes
+ * this class a container for the nets.
+ */
+class NETINFO_LIST
+{
+    friend class BOARD;
+
+public:
+    NETINFO_LIST( BOARD* aParent );
+    ~NETINFO_LIST();
+
+    /**
+     * Function GetItem
+     * @param aNetCode = netcode to identify a given NETINFO_ITEM
+     * @return NETINFO_ITEM* - by \a aNetCode, or NULL if not found
+     */
+    NETINFO_ITEM* GetNetItem( int aNetCode ) const;
+
+    /**
+     * Function GetItem
+     * @param aNetName = net name to identify a given NETINFO_ITEM
+     * @return NETINFO_ITEM* - by \a aNetName, or NULL if not found
+     */
+    NETINFO_ITEM* GetNetItem( const wxString& aNetName ) const;
+
+    /**
+     * Function GetNetCount
+     * @return the number of nets ( always >= 1 )
+     * because the first net is the "not connected" net and always exists
+     */
+    unsigned GetNetCount() const { return m_netNames.size(); }
+
+    /**
+     * Function AppendNet
+     * adds \a aNewElement to the end of the net list. Negative net code means it is going to be
+     * auto-assigned.
+     */
+    void AppendNet( NETINFO_ITEM* aNewElement );
+
+    /**
+     * Function RemoveNet
+     * Removes a new from the net list.
+     */
+    void RemoveNet( NETINFO_ITEM* aNet );
+    /**
+     * Function GetPadCount
+     * @return the number of pads in board
+     */
+    unsigned GetPadCount() const                { return m_PadsFullList.size(); }
+
+    /**
+     * Function GetPads
+     * returns a list of all the pads (so long as buildPadsFullList() has
+     * been recently called).  Returned list contains non-owning pointers.
+     * @return D_PADS& - a full list of pads
+     */
+    const D_PADS& GetPads() const  { return m_PadsFullList; }
+
+    /// Return the name map, at least for python.
+    const NETNAMES_MAP& GetNets() const         { return  m_netNames; }
+
+    /**
+     * Function GetPad
+     * @return D_PAD* - the pad from m_PadsFullList or nullptr if bad @a aIdx
+     */
+    D_PAD* GetPad( unsigned aIdx ) const;
+
+    bool DeletePad( D_PAD* aPad );
+
+    ///> Constant that holds the "unconnected net" number (typically 0)
+    ///> all items "connected" to this net are actually not connected items
+    static const int UNCONNECTED;
+
+    ///> Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED
+    ///> (typically -1) when calling SetNetCode od board connected items
+    static const int ORPHANED;
+
+    ///> NETINFO_ITEM meaning that there was no net assigned for an item, as there was no
+    ///> board storing net list available.
+    static NETINFO_ITEM ORPHANED_ITEM;
+
+#if defined(DEBUG)
+    void Show() const;
+#endif
+
+#ifndef SWIG
+    ///> Wrapper class, so you can iterate through NETINFO_ITEM*s, not
+    ///> std::pair<int/wxString, NETINFO_ITEM*>
+    class iterator
+    {
+    public:
+        iterator( NETNAMES_MAP::const_iterator aIter ) : m_iterator( aIter )
+        {
+        }
+
+        /// pre-increment operator
+        const iterator& operator++()
+        {
+            ++m_iterator;
+            return *this;
+        }
+
+        /// post-increment operator
+        iterator operator++( int )
+        {
+            iterator ret = *this;
+            ++m_iterator;
+            return ret;
+        }
+
+        NETINFO_ITEM* operator*() const
+        {
+            return m_iterator->second;
+        }
+
+        NETINFO_ITEM* operator->() const
+        {
+            return m_iterator->second;
+        }
+
+        bool operator!=( const iterator& aOther ) const
+        {
+            return m_iterator != aOther.m_iterator;
+        }
+
+        bool operator==( const iterator& aOther ) const
+        {
+            return m_iterator == aOther.m_iterator;
+        }
+
+    private:
+        NETNAMES_MAP::const_iterator m_iterator;
+    };
+
+    iterator begin() const
+    {
+        return iterator( m_netNames.begin() );
+    }
+
+    iterator end() const
+    {
+        return iterator( m_netNames.end() );
+    }
+#endif
+
+    BOARD* GetParent() const
+    {
+        return m_Parent;
+    }
+
+private:
+    /**
+     * Function clear
+     * deletes the list of nets (and free memory)
+     */
+    void clear();
+
+    /**
+     * Function buildListOfNets
+     * builds or rebuilds the list of NETINFO_ITEMs
+     * The list is sorted by names.
+     */
+    void buildListOfNets();
+
+    /**
+     * Function buildPadsFullList
+     * creates the pad list, and initializes:
+     *   m_Pads (list of pads)
+     * set m_Status_Pcb = LISTE_PAD_OK;
+     * and clear for all pads in list the m_SubRatsnest member;
+     * clear m_Pcb->m_FullRatsnest
+     */
+    void buildPadsFullList();
+
+    /**
+     * Function getFreeNetCode
+     * returns the first available net code that is not used by any other net.
+     */
+    int getFreeNetCode();
+
+    BOARD* m_Parent;
+
+    NETNAMES_MAP m_netNames;        ///< map of <wxString, NETINFO_ITEM*>, is NETINFO_ITEM owner
+    NETCODES_MAP m_netCodes;        ///< map of <int, NETINFO_ITEM*> is NOT owner
+
+    D_PADS  m_PadsFullList;         ///< contains all pads, sorted by pad's netname.
+                                    ///< can be used in ratsnest calculations.
+
+    int m_newNetCode;               ///< possible value for new net code assignment
 };
 
 
@@ -731,4 +707,4 @@ enum StatusPcbFlags {
 };
 
 
-#endif  // __CLASSES_NETINFO__
+#endif  // CLASS_NETINFO_
diff --git a/pcbnew/class_netinfolist.cpp b/pcbnew/class_netinfolist.cpp
index 7574aaa286..dbfe2d82c4 100644
--- a/pcbnew/class_netinfolist.cpp
+++ b/pcbnew/class_netinfolist.cpp
@@ -69,6 +69,28 @@ void NETINFO_LIST::clear()
 }
 
 
+NETINFO_ITEM* NETINFO_LIST::GetNetItem( int aNetCode ) const
+{
+    NETCODES_MAP::const_iterator result = m_netCodes.find( aNetCode );
+
+    if( result != m_netCodes.end() )
+        return (*result).second;
+
+    return NULL;
+}
+
+
+NETINFO_ITEM* NETINFO_LIST::GetNetItem( const wxString& aNetName ) const
+{
+    NETNAMES_MAP::const_iterator result = m_netNames.find( aNetName );
+
+    if( result != m_netNames.end() )
+        return (*result).second;
+
+    return NULL;
+}
+
+
 void NETINFO_LIST::RemoveNet( NETINFO_ITEM* aNet )
 {
     for( NETCODES_MAP::iterator i = m_netCodes.begin(); i != m_netCodes.end(); ++i )
@@ -121,6 +143,32 @@ void NETINFO_LIST::AppendNet( NETINFO_ITEM* aNewElement )
 }
 
 
+D_PAD* NETINFO_LIST::GetPad( unsigned aIdx ) const
+{
+    if( aIdx < m_PadsFullList.size() )
+        return m_PadsFullList[aIdx];
+    else
+        return NULL;
+}
+
+
+bool NETINFO_LIST::DeletePad( D_PAD* aPad )
+{
+    std::vector<D_PAD*>::iterator it  = m_PadsFullList.begin();
+    std::vector<D_PAD*>::iterator end = m_PadsFullList.end();
+
+    for( ; it != end;  ++it )
+    {
+        if( *it == aPad )
+        {
+            m_PadsFullList.erase( it );
+            return true;
+        }
+    }
+    return false;
+}
+
+
 /* sort function, to sort pad list by netnames
  * this is a case sensitive sort.
  * DO NOT change it because NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname )
diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h
index 03e59483fc..12223ab040 100644
--- a/pcbnew/class_pad.h
+++ b/pcbnew/class_pad.h
@@ -581,6 +581,7 @@ private:    // Private variable members:
     // Actually computed and cached on demand by the accessor
     mutable int m_boundingRadius;  ///< radius of the circle containing the pad shape
 
+#ifndef SWIG
     /// Pad name (4 char) or a long identifier (used in pad name
     /// comparisons because this is faster than string comparison)
     union
@@ -589,6 +590,7 @@ private:    // Private variable members:
         char        m_Padname[PADNAMEZ];    // zero padded at end to full size
         wxUint32    m_NumPadName;           // same number of bytes as m_Padname[]
     };
+#endif
 
     wxPoint     m_Pos;              ///< pad Position on board
 
diff --git a/pcbnew/io_mgr.h b/pcbnew/io_mgr.h
index 24d548a08a..87e217a045 100644
--- a/pcbnew/io_mgr.h
+++ b/pcbnew/io_mgr.h
@@ -445,6 +445,7 @@ public:
     };
 
 
+#ifndef SWIG
     /**
      * Class RELEASER
      * releases a PLUGIN in the context of a potential thrown exception, through
@@ -495,6 +496,7 @@ public:
             return plugin;
         }
     };
+#endif
 };
 
 #endif // IO_MGR_H_
diff --git a/pcbnew/scripting/board.i b/pcbnew/scripting/board.i
index da0e10aa01..8073257d07 100644
--- a/pcbnew/scripting/board.i
+++ b/pcbnew/scripting/board.i
@@ -70,7 +70,8 @@
 // std::vector templates
 
 %template(VIA_DIMENSION_Vector) std::vector<VIA_DIMENSION>;
-%template (RATSNEST_Vector) std::vector<RATSNEST_ITEM>;
+%template(RATSNEST_Vector)      std::vector<RATSNEST_ITEM>;
+
 
 %extend BOARD
 {
@@ -115,3 +116,16 @@
         self.SetEnd0(end)
     }
 }
+
+
+%feature("notabstract")     NETINFO_ITEM;
+
+// http://swig.10945.n7.nabble.com/std-containers-and-pointers-td3728.html
+%{
+    namespace swig {
+        template <>  struct traits<NETINFO_ITEM> {
+            typedef pointer_category category;
+            static const char* type_name() { return "NETINFO_ITEM"; }
+        };
+    }
+%}
diff --git a/pcbnew/scripting/pcbnew.i b/pcbnew/scripting/pcbnew.i
index 1e69396483..782de685b0 100644
--- a/pcbnew/scripting/pcbnew.i
+++ b/pcbnew/scripting/pcbnew.i
@@ -35,17 +35,22 @@
 %include "docstrings.i"
 #endif
 
+
 %include "kicad.i"
 
-// ignore a couple of items that generate warnings from swig built code
+%include <convert_to_biu.h>
+%include <fpid.h>
 
-%ignore NETINFO_ITEM;
+// ignore a couple of items that generate warnings from swig built code
 %ignore BOARD_ITEM::ZeroOffset;
 %ignore D_PAD::m_PadSketchModePenSize;
 
+class BASE_SET {};
+%ignore BASE_SET;
+
+
 // rename the Add method of classes to Add native, so we will handle
 // the Add method in python
-
 %rename(AddNative) *::Add;
 
 // fix method names conflicts
@@ -85,16 +90,14 @@
   #include <wx_python_helpers.h>
   #include <class_board_item.h>
   #include <class_board_connected_item.h>
+  #include <class_netinfo.h>
   #include <class_board_design_settings.h>
-  #include <class_board.h>
   #include <class_module.h>
   #include <class_track.h>
   #include <class_zone.h>
   #include <zones.h>
   #include <layers_id_colors_and_visibility.h>
   #include <class_pad.h>
-  #include <pad_shapes.h>
-  #include <class_netinfo.h>
   #include <class_pcb_text.h>
   #include <class_dimension.h>
   #include <class_drawsegment.h>
@@ -102,16 +105,19 @@
   #include <class_mire.h>
   #include <class_text_mod.h>
   #include <class_edge_mod.h>
-  #include <dlist.h>
-  #include <class_zone_settings.h>
+
   #include <class_netclass.h>
-  #include <class_netinfo.h>
+  #include <colors.h>
+
+  //#include <dlist.h>
+  #include <class_zone_settings.h>
   #include <pcbnew_scripting_helpers.h>
 
   #include <plotcontroller.h>
   #include <pcb_plot_params.h>
   #include <exporters/gendrill_Excellon_writer.h>
-  #include <colors.h>
+
+  #include <class_board.h>
 
   BOARD *GetBoard(); /* get current editor board */
 %}
@@ -124,16 +130,14 @@
 
 %include <class_board_item.h>
 %include <class_board_connected_item.h>
-%include <class_board_design_settings.h>
-%include <class_board.h>
+%include <pad_shapes.h>
+%include <class_pad.h>
+%include <class_netinfo.h>
 %include <class_module.h>
 %include <class_track.h>
 %include <class_zone.h>
 %include <zones.h>
 %include <layers_id_colors_and_visibility.h>
-%include <class_pad.h>
-%include <pad_shapes.h>
-%include <class_netinfo.h>
 %include <class_pcb_text.h>
 %include <class_dimension.h>
 %include <class_drawsegment.h>
@@ -144,14 +148,16 @@
 %include <dlist.h>
 %include <class_zone_settings.h>
 %include <class_netclass.h>
-%include <class_netinfo.h>
 
+%include <class_board_design_settings.h>
 %include <plotcontroller.h>
 %include <pcb_plot_params.h>
 %include <plot_common.h>
 %include <exporters/gendrill_Excellon_writer.h>
 %include <colors.h>
 
+%include <class_board.h>
+
 %include "board_item.i"
 
 %include <pcbnew_scripting_helpers.h>
@@ -167,6 +173,8 @@
 %include "plugins.i"
 %include "units.i"
 
+
+
 // Extend LSET by 2 methods to add or remove layers from the layer list
 // Mainly used to add or remove layers of a pad layer list
 %extend LSET
diff --git a/polygon/PolyLine.h b/polygon/PolyLine.h
index b60cd37ca6..d6a1f89295 100644
--- a/polygon/PolyLine.h
+++ b/polygon/PolyLine.h
@@ -104,6 +104,8 @@ public:
     { return (x != cpt2.x) || (y != cpt2.y) || (end_contour != cpt2.end_contour); }
 };
 
+
+#ifndef SWIG
 /**
  * CPOLYGONS_LIST handle a list of contours (polygons corners).
  * Each corner is a CPolyPt item.
@@ -205,6 +207,8 @@ public:
      */
     int GetContoursCount() const;
 };
+#endif
+
 
 class CPolyLine
 {
diff --git a/scripting/kicad.i b/scripting/kicad.i
index 6316a6dcae..58194a2550 100644
--- a/scripting/kicad.i
+++ b/scripting/kicad.i
@@ -31,21 +31,37 @@
 %include <std_basic_string.i>
 %include <std_string.i>
 %include <std_map.i>
+%include <std_shared_ptr.i>
 
-/* ignore some constructors of EDA_ITEM that will make the build fail */
+/*
+http://www.swig.org/Doc3.0/CPlusPlus11.html
+7.3.3 Hash tables
 
-%nodefaultctor EDA_ITEM;
+The new hash tables in the STL are unordered_set, unordered_multiset,
+unordered_map, unordered_multimap. These are not available in SWIG, but in
+principle should be easily implemented by adapting the current STL containers.
+
+%include <std_unordered_map.i>
+*/
+
+// ignore some constructors of EDA_ITEM that will make the build fail
+
+%nodefaultctor      EDA_ITEM;
 %ignore EDA_ITEM::EDA_ITEM( EDA_ITEM* parent, KICAD_T idType );
 %ignore EDA_ITEM::EDA_ITEM( KICAD_T idType );
 %ignore EDA_ITEM::EDA_ITEM( const EDA_ITEM& base );
 
+
+%warnfilter(401)    EDA_ITEM;
+%warnfilter(509)    UTF8;
+
 /* swig tries to wrap SetBack/SetNext on derived classes, but this method is
    private for most childs, so if we don't ignore it won't compile */
 
 %ignore EDA_ITEM::SetBack;
 %ignore EDA_ITEM::SetNext;
 
-/* ignore other functions that cause trouble */
+// ignore other functions that cause trouble
 
 %ignore InitKiCadAbout;
 %ignore GetCommandOptions;
@@ -55,9 +71,10 @@
 %ignore operator=;
 
 
-/* headers/imports that must be included in the _wrapper.cpp at top */
+// headers/imports that must be included in the _wrapper.cpp at top
 
 %{
+    #include <macros.h>
     #include <cstddef>
     #include <dlist.h>
     #include <base_struct.h>
@@ -75,27 +92,13 @@
     #include <convert_to_biu.h>
 %}
 
-/* all the wx wrappers for wxString, wxPoint, wxRect, wxChar .. */
+// all the wx wrappers for wxString, wxPoint, wxRect, wxChar ..
 %include <wx.i>
 
-/* exception handling */
-
-/* the IO_ERROR exception handler, not working yet... */
-/*
-%exception
-{
-  try {
-  $function
-  }
-  catch (IO_ERROR e) {
-    PyErr_SetString(PyExc_IOError,"IO error");
-    return NULL;
-  }
-}
-*/
-
-/* header files that must be wrapped */
+// header files that must be wrapped
 
+%include <macros.h>
+%include <core/typeinfo.h>
 %include <dlist.h>
 %include <base_struct.h>
 %include <class_eda_rect.h>
@@ -104,13 +107,11 @@
 %include <class_colors_design_settings.h>
 %include <class_marker_base.h>
 %include <eda_text.h>
-%include <convert_to_biu.h>
-%include <fpid.h>
 
-/* special iteration wrapper for DLIST objects */
+// special iteration wrapper for DLIST objects
 %include "dlist.i"
 
-/* std template mappings */
+// std template mappings
 %template(intVector) std::vector<int>;
 %template(str_utf8_Map) std::map< std::string,UTF8 >;
 
@@ -120,7 +121,7 @@
 // TODO: wrapper of BASE_SET (see std::bitset<LAYER_ID_COUNT> BASE_SET;)
 
 
-/* KiCad plugin handling */
+// KiCad plugin handling
 %include "kicadplugins.i"
 
 // map CPolyLine and classes used in CPolyLine:
diff --git a/scripting/wx.i b/scripting/wx.i
index aa03a3f432..dddd68391b 100644
--- a/scripting/wx.i
+++ b/scripting/wx.i
@@ -166,8 +166,9 @@ public:
         wxPoint __sub__(const wxPoint& pt) {   return *self - pt;  }
 
         void Set(long x, long y) {  self->x = x;     self->y = y;  }
+
         PyObject* Get()
-    {
+        {
             PyObject* tup = PyTuple_New(2);
             PyTuple_SET_ITEM(tup, 0, PyInt_FromLong(self->x));
             PyTuple_SET_ITEM(tup, 1, PyInt_FromLong(self->y));
@@ -199,21 +200,78 @@ public:
 
 /* they handle the conversion from/to strings */
 
-%typemap(in) wxChar {   wxString str = Py2wxString($input); $1 = str[0];   }
+%typemap(in)  wxChar {  wxString str = Py2wxString($input); $1 = str[0];   }
 %typemap(out) wxChar {  wxString str($1);      $result = wx2PyString(str); }
 
-// wxString wrappers /////////////////////////////////////////////////////////
 
-%typemap(out) wxString&
+// wxString /////////////////////////////////////////////////////////
+
+/*
+    The wxString typemaps below are sufficient to handle two cases but not
+    a third.
+
+    1) Arguments into wrapped C++ functions taking wxString as parameters can be
+    passed as python strings, not wxString. In fact you cannot create a wxString
+    from python, only in C++.
+
+    2) Wrapped C++ functions returning wxString will have that wxString
+    converted to a python unicode or string automatically.
+
+    Both of these features are a result of the wxString typemaps below. Note
+    that this philosophy is very agreeable, and is consistent with the
+    philosophy adopted by wxPython. In fact one might wish that KiCad did not
+    use wxString in any of its data structures, and merely used UTF8s, which
+    will convert automatically to and from wxString when needed.
+
+    There is another case that typemaps to not address, and no, this is not the
+    construction of wxString from python, but rather the examination of wxString
+    in situ, i.e. in a data structure within the BOARD. It does not match either
+    case above. So the class wxString {} spec block below is in here to allow
+    examination of a wxString's value when operating python interactively or
+    when printing a value in situ that was not returned from a wrapped function.
+    Remember wxString return values of functions are converted by the typemaps.
+
+    No wxString constructor is given to SWIG, since wxString contruction is
+    always done in C++, but python needs to know that it can delete a wxString
+    when necessary. And most importantly we need to see a string's contents so
+    the __str__() function must show content.
+
+*/
+
+class wxString
 {
-%#if wxUSE_UNICODE
-    $result = PyUnicode_FromWideChar($1->c_str(), $1->Len());
-%#else
-    $result = PyString_FromStringAndSize($1->c_str(), $1->Len());
-%#endif
+public:
+    // this is not C++ source, it is SWIG interface spec
+    virtual ~wxString();
+
+    %extend
+    {
+        PyObject* __str__()
+        {
+    %#if wxUSE_UNICODE
+            return PyUnicode_FromWideChar( $self->c_str(), $self->Len() );
+    %#else
+            return PyString_FromStringAndSize( $self->c_str(), $self->Len() );
+    %#endif
+        }
+    }
+
+    %pythoncode
+    {
+        def __repr__(self):     return 'wxString(\'' + self.__str__() + '\')'
+    }
+};
+
+
+// wxString typemaps
+
+%typemap(in) wxString {
+    wxString* sptr = newWxStringFromPy($input);
+    if (sptr == NULL) SWIG_fail;
+    $1 = *sptr;
+    delete sptr;
 }
 
-%apply wxString& { wxString* }
 
 %typemap(out) wxString
 {
@@ -224,6 +282,7 @@ public:
 %#endif
 }
 
+
 %typemap(varout) wxString
 {
 %#if wxUSE_UNICODE
@@ -233,6 +292,7 @@ public:
 %#endif
 }
 
+
 %typemap(in) wxString& (bool temp=false)
 {
     $1 = newWxStringFromPy($input);
@@ -240,26 +300,30 @@ public:
     temp = true;
 }
 
+
+%typemap(out) wxString&
+{
+%#if wxUSE_UNICODE
+    $result = PyUnicode_FromWideChar($1->c_str(), $1->Len());
+%#else
+    $result = PyString_FromStringAndSize($1->c_str(), $1->Len());
+%#endif
+}
+
 %typemap(freearg) wxString&
 {
     if (temp$argnum)
         delete $1;
 }
 
-
-%typemap(in) wxString {
-    wxString* sptr = newWxStringFromPy($input);
-    if (sptr == NULL) SWIG_fail;
-    $1 = *sptr;
-    delete sptr;
-}
-
 %typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER) wxString& {
     $1 = PyString_Check($input) || PyUnicode_Check($input);
 }
 
+%apply wxString& { wxString* }
 
-// wxArrayString wrappers //////////////////////////////////////////////////////
+
+// wxArrayString //////////////////////////////////////////////////////
 %typemap(in) wxArrayString& (bool temp=false) {
     if (!PySequence_Check($input))
     {