diff --git a/src/command_line_options.cpp b/src/command_line_options.cpp
index 9906316..fffd8e1 100644
--- a/src/command_line_options.cpp
+++ b/src/command_line_options.cpp
@@ -218,9 +218,7 @@ CommandLineParser::init_ini(Options* opts)
     ("dpad-only", &opts->uinput_config.dpad_only)
     ("force-feedback", &opts->uinput_config.force_feedback)
     ("extra-devices", &opts->uinput_config.extra_devices)
-    // mimic_xpad()
-    // btn_map
-    // axis_map
+    // FIXME: mimic_xpad()
     ;
 
   m_ini.section("ui-buttonmap", boost::bind(&CommandLineParser::set_ui_buttonmap, this, _1, _2));
@@ -277,8 +275,8 @@ CommandLineParser::set_ui_axismap_from_string(const std::string& str)
   }
   else
   {
-    set_axismap(str.substr(0, i),
-                str.substr(i+1, str.size()-i));
+    set_ui_axismap(str.substr(0, i),
+                   str.substr(i+1, str.size()-i));
   }
 }
 
@@ -789,17 +787,7 @@ CommandLineParser::set_ui_buttonmap(const std::string& name, const std::string&
 void
 CommandLineParser::set_axismap(const std::string& name, const std::string& value)
 {
-  XboxAxis  axis  = string2axis(name);
-  AxisEvent event = AxisEvent::from_string(value);
-            
-  if (axis != XBOX_AXIS_UNKNOWN)
-  {
-    m_options->uinput_config.axis_map[axis] = event;
-  }
-  else
-  {
-    throw std::runtime_error("Couldn't convert string \"" + value + "\" to ui-axis-mapping");
-  }      
+  m_options->axis_map.push_back(AxisMapping::from_string(name, value));
 }
 
 void
diff --git a/src/evdev_helper.cpp b/src/evdev_helper.cpp
index 0442593..5bae06f 100644
--- a/src/evdev_helper.cpp
+++ b/src/evdev_helper.cpp
@@ -671,7 +671,7 @@ int get_event_type(const std::string& name)
   }
   else
   {
-    throw std::runtime_error("str2event(): unknown event type prefix: " + name);
+    throw std::runtime_error("get_event_type(): unknown event type prefix: " + name);
   }
 }
 
diff --git a/src/ini_schema.cpp b/src/ini_schema.cpp
index f76efa6..823a541 100644
--- a/src/ini_schema.cpp
+++ b/src/ini_schema.cpp
@@ -20,13 +20,6 @@
 
 #include <sstream>
 
-class INIPairSchema
-{
-public:
-  virtual ~INIPairSchema() {}
-  virtual std::string str() const = 0;
-};
-
 class INIPairSchemaBool : public INIPairSchema
 {
 private:
@@ -128,7 +121,10 @@ private:
   boost::function<void (const std::string&)> m_callback;
   
 public:
-  INIPairSchemaCallback(boost::function<void (const std::string&)> callback) : m_callback(callback) {}
+  INIPairSchemaCallback(boost::function<void (const std::string&)> callback) : 
+    m_callback(callback) 
+  {}
+
   void call(const std::string& value)
   {
     if (m_callback)
@@ -142,7 +138,8 @@ public:
   }
 };
 
-INISchemaSection::INISchemaSection()
+INISchemaSection::INISchemaSection(boost::function<void (const std::string&, const std::string&)> callback) :
+  m_callback(callback)
 {
 }
 
@@ -204,6 +201,20 @@ INISchemaSection::operator()(const std::string& name, boost::function<void (cons
   return *this;
 }
 
+INIPairSchema*
+INISchemaSection::get(const std::string& name) const
+{
+  Schema::const_iterator i = m_schema.find(name);
+  if (i == m_schema.end())
+  {
+    return 0;
+  }
+  else
+  {
+    return i->second;
+  }
+}
+
 void
 INISchemaSection::save(std::ostream& out)
 {
@@ -243,15 +254,15 @@ INISchema::section(const std::string& name,
     delete i->second;
   }
 
-  INISchemaSection* section = new INISchemaSection();
+  INISchemaSection* section = new INISchemaSection(callback);
   m_sections.insert(std::pair<std::string, INISchemaSection*>(name, section));
   return *section;
 }
 
 INISchemaSection*
-INISchema::get_section(const std::string& name)
+INISchema::get_section(const std::string& name) const
 {
-  Sections::iterator i = m_sections.find(name);
+  Sections::const_iterator i = m_sections.find(name);
   if (i != m_sections.end())
   {
     return i->second;
diff --git a/src/ini_schema.hpp b/src/ini_schema.hpp
index 3947209..7db4732 100644
--- a/src/ini_schema.hpp
+++ b/src/ini_schema.hpp
@@ -23,7 +23,14 @@
 #include <string>
 #include <boost/function.hpp>
 
-class INIPairSchema;
+class INIPairSchema
+{
+public:
+  INIPairSchema() {}
+  virtual ~INIPairSchema() {}
+  virtual std::string str() const =0;
+  virtual void call(const std::string& value) =0;
+};
 
 class INISchemaSection
 {
@@ -32,7 +39,10 @@ private:
   Schema m_schema;
 
 public:
-  INISchemaSection();
+  boost::function<void (const std::string&, const std::string&)> m_callback;
+
+public:
+  INISchemaSection(boost::function<void (const std::string&, const std::string&)> callback);
   ~INISchemaSection();
 
   INISchemaSection& operator()(const std::string& name, bool*  value);
@@ -41,6 +51,8 @@ public:
   INISchemaSection& operator()(const std::string& name, std::string* value);
   INISchemaSection& operator()(const std::string& name, boost::function<void (const std::string&)> callback);
 
+  INIPairSchema* get(const std::string& name) const;
+
   void save(std::ostream& out);
 
 private:
@@ -67,7 +79,7 @@ public:
                             boost::function<void (const std::string&, const std::string&)> callback 
                             = boost::function<void (const std::string&, const std::string&)>());
 
-  INISchemaSection* get_section(const std::string& name);
+  INISchemaSection* get_section(const std::string& name) const;
 
   void save(std::ostream& out);
 
diff --git a/src/ini_schema_builder.cpp b/src/ini_schema_builder.cpp
index 68a9e52..4e046f0 100644
--- a/src/ini_schema_builder.cpp
+++ b/src/ini_schema_builder.cpp
@@ -18,6 +18,8 @@
 
 #include "ini_schema_builder.hpp"
 
+#include "ini_schema.hpp"
+
 INISchemaBuilder::INISchemaBuilder(const INISchema& schema) :
   m_schema(schema)
 {
@@ -26,11 +28,36 @@ INISchemaBuilder::INISchemaBuilder(const INISchema& schema) :
 void
 INISchemaBuilder::send_section(const std::string& section)
 {
+  m_current_section = section;
 }
 
 void
 INISchemaBuilder::send_pair(const std::string& name, const std::string& value)
 {
+  INISchemaSection* section = m_schema.get_section(m_current_section);
+  if (!section)
+  {
+    throw std::runtime_error("unknown section: '" + m_current_section + "'");
+  }
+  else
+  {
+    if (section->m_callback)
+    {
+      section->m_callback(name, value);
+    }
+    else
+    {
+      INIPairSchema* pair = section->get(name);
+      if (!pair)
+      {
+        throw std::runtime_error("unknown name: '" + name + "'");
+      }
+      else
+      {
+        pair->call(value);
+      }
+    }
+  }
 }
 
 /* EOF */
diff --git a/src/ini_schema_builder.hpp b/src/ini_schema_builder.hpp
index a86a670..835b325 100644
--- a/src/ini_schema_builder.hpp
+++ b/src/ini_schema_builder.hpp
@@ -27,6 +27,7 @@ class INISchemaBuilder : public INIBuilder
 {
 private:
   const INISchema& m_schema;
+  std::string m_current_section;  
 
 public:
   INISchemaBuilder(const INISchema& schema);