Index: SConscript
===================================================================
--- SConscript	(revision 2449)
+++ SConscript	(working copy)
@@ -281,7 +281,9 @@
  controlobjectthreadwidget.cpp controlobjectthreadmain.cpp controlevent.cpp controllogpotmeter.cpp controlobject.cpp controlnull.cpp controlpotmeter.cpp
  controlpushbutton.cpp controlttrotary.cpp controlbeat.cpp dlgpreferences.cpp dlgprefsound.cpp dlgprefmididevice.cpp dlgprefmidibindings.cpp dlgprefplaylist.cpp dlgprefcontrols.cpp dlgbpmtap.cpp dlgprefbpm.cpp dlgbpmscheme.cpp dlgabout.cpp
  dlgprefeq.cpp dlgprefcrossfader.cpp enginebuffer.cpp enginebufferscale.cpp enginebufferscalelinear.cpp engineclipping.cpp enginefilterblock.cpp enginefilteriir.cpp  enginefilter.cpp engineobject.cpp
- enginepregain.cpp enginevolume.cpp main.cpp midiobject.cpp midiobjectnull.cpp mididevicehandler.cpp mixxx.cpp mixxxview.cpp
+ enginepregain.cpp enginevolume.cpp main.cpp 
+  mididevice.cpp midideviceportmidi.cpp mididevicemanager.cpp midicontrolprocessor.cpp midilearningprocessor.cpp 
+  mixxx.cpp mixxxview.cpp
  soundsourcemp3.cpp soundsourceoggvorbis.cpp enginechannel.cpp enginemaster.cpp wwidget.cpp wpixmapstore.cpp wlabel.cpp wnumber.cpp wnumberpos.cpp wnumberrate.cpp wnumberbpm.cpp wknob.cpp wdisplay.cpp wvumeter.cpp wpushbutton.cpp wslidercomposed.cpp wslider.cpp  wstatuslight.cpp enginedelay.cpp engineflanger.cpp enginespectralfwd.cpp mathstuff.cpp readerextract.cpp readerextractwave.cpp
  readerevent.cpp rtthread.cpp windowkaiser.cpp probabilityvector.cpp reader.cpp enginevumeter.cpp peaklist.cpp rotary.cpp log.cpp
  track.cpp trackcollection.cpp trackplaylist.cpp wtracktableview.cpp wtracktablemodel.cpp wpromotracksmodel.cpp proxymodel.cpp xmlparse.cpp trackimporter.cpp parser.cpp parserpls.cpp parserm3u.cpp
@@ -306,18 +308,7 @@
 #elif platform == 'win32':
 #	sources += Split("""powermatewin.cpp mousewin.cpp """)
 
-#Compile platform specific MIDI support
-if platform == 'linux':
-	sources += Split("""midiobjectalsaseq.cpp """)  #ALSA Sequencer MIDI support for Linux
-	env.Append(CXXFLAGS = '-D__ALSASEQMIDI__')
-elif platform == 'win32':
-	sources += Split("""midiobjectwin.cpp """)	  #Windows MIDI support
-	env.Append(CXXFLAGS = '-D__WINMIDI__')
-elif platform == 'osx':
-	sources += Split("""midiobjectcoremidi.cpp """) #CoreMidi support for OS X
-	env.Append(CXXFLAGS = '-D__COREMIDI__')
 
-
 #Set up the library path on Windows:
 if platform == 'win32':
 	env.Append(CPPPATH=['../../../mixxx-winlib', '../../lib/ladspa']) #If you add more directories, separate them with a semicolon (;)
@@ -356,16 +347,16 @@
 	CheckFFMPEG(conf, sources)
 
 	#PortMidi backend support
-	flags_portmidi = getFlags(env, 'portmidi', 0)
-	if int(flags_portmidi):
-		if not conf.CheckLib(['portmidi', 'libportmidi']):
-			print "Did not find portmidi or it\'s development headers, exiting!"
-			Exit(1)
-		#if not conf.CheckLib(['porttime', 'libporttime']):
-		#	print "Did not find porttime or it\'s development headers, exiting!"
-		#	Exit(1)
-		sources += Split("""midiobjectportmidi.cpp """); 
-		env.Append(CXXFLAGS = '-D__PORTMIDI__')
+	#flags_portmidi = getFlags(env, 'portmidi', 0)
+	#if int(flags_portmidi):
+	if not conf.CheckLib(['portmidi', 'libportmidi']):
+		print "Did not find portmidi or it\'s development headers, exiting!"
+		Exit(1)
+	env.Append(CXXFLAGS = '-D__PORTMIDI__')
+	#if not conf.CheckLib(['porttime', 'libporttime']):
+	#	print "Did not find porttime or it\'s development headers, exiting!"
+	#	Exit(1)
+	#sources += Split("""midiobjectportmidi.cpp """); 
 	
 
 	#Platform-specific checks for Linux and Win32...
Index: dlgprefmididevice.cpp
===================================================================
--- dlgprefmididevice.cpp	(revision 2449)
+++ dlgprefmididevice.cpp	(working copy)
@@ -18,32 +18,38 @@
 #include <QtCore>
 #include "dlgprefmididevice.h"
 #include "midiledhandler.h"
+#include "mididevicemanager.h"
+#include "mididevice.h"
 #include "wwidget.h"
 
-#define DEVICE_CONFIG_PATH QDir::homePath().append("/").append(".MixxxMIDIDevices")
-
 static QString toHex(QString numberStr) {
     return "0x" + QString("0" + QString::number(numberStr.toUShort(), 16).toUpper()).right(2);
 }
 
-DlgPrefMidiDevice::DlgPrefMidiDevice(QWidget *parent, MidiObject *midi, ConfigObject<ConfigValue> *pConfig) :  QWidget(parent), Ui::DlgPrefMidiDeviceDlg() {
+DlgPrefMidiDevice::DlgPrefMidiDevice(QWidget *parent, MidiDeviceManager *midi, ConfigObject<ConfigValue> *pConfig) :  QWidget(parent), Ui::DlgPrefMidiDeviceDlg() {
     setupUi(this);
 
     m_pConfig = pConfig;
 
-    // TODO: use #define for filename
-    m_pDeviceSettings = new ConfigObject<ConfigValue>(DEVICE_CONFIG_PATH);
-
-    // Open midi
-    m_pMidi = midi;
-
+    m_pMidiDeviceManager = midi;
+    m_pDeviceSettings = midi->getDeviceSettings();
+    
     // Store default midi device
     //m_pConfig->set(ConfigKey("[Midi]","Device"), ConfigValue(m_pMidi->getOpenDevice()));
 
     // Midi devices
     listMidiDevices->clear();
-    QStringList * midiDeviceList = m_pMidi->getDeviceList();
-    listMidiDevices->addItems(*midiDeviceList);
+    QList<MidiDevice*> midiDeviceList = m_pMidiDeviceManager->getDeviceList();
+    
+    QListIterator<MidiDevice*> dev_it(midiDeviceList);
+    MidiDevice* curDevice;
+    qDebug() << "DlgPrefMidiDevice: midi device list has " << midiDeviceList.count() << " devices!";
+    while (dev_it.hasNext())
+    {
+    	curDevice = dev_it.next();
+    	listMidiDevices->addItem(curDevice->getName());
+    }
+    //listMidiDevices->addItems(*midiDeviceList);
 
     // Set up send/receive enable/disable options - disabled initially
     comboMidiRxEnable->addItem("Disabled", false);
@@ -81,6 +87,7 @@
 bool DlgPrefMidiDevice::eventFilter(QObject * o, QEvent * e)
 {
     if (e->type() == QEvent::Hide) tblDebug->setRowCount(0);
+    return false; //Let the event be handled further
 }
 
 DlgPrefMidiDevice::~DlgPrefMidiDevice() {
@@ -100,7 +107,7 @@
 }
 
 void DlgPrefMidiDevice::slotUpdate() {
-	m_pMidi->enableDebug(this);
+	//m_pMidi->enableDebug(this);
 }
 
 void DlgPrefMidiDevice::slotApply() {
@@ -109,7 +116,11 @@
 		saveSettings(labelDeviceName->text(), comboMidiRxEnable->currentText(), comboMidiTxEnable->currentText());
 		m_pDeviceSettings->Save();
 	}
-	m_pMidi->disableDebug();
+	
+    //Close all the MIDI devices and open whatever ones are selected.
+    m_pMidiDeviceManager->setupDevices();
+    
+	//m_pMidi->disableDebug();
 }
 
 // Called when a MIDI device is selected
@@ -131,44 +142,49 @@
 void DlgPrefMidiDevice::slotUpdateEnabled() {
 	if (deviceEnabled()) { // Is the device enabled or disabled
 		labelDeviceStatus->setText("Enabled");
-		m_pMidi->devOpen(labelDeviceName->text());
+		//ALBERT
+		//m_pMidi->devOpen(labelDeviceName->text());
 	} else {
 		labelDeviceStatus->setText("Disabled");
-		m_pMidi->devClose(labelDeviceName->text());
+		//ALBERT
+		//m_pMidi->devClose(labelDeviceName->text());
 	}
 	// Update device rx/tx status
-	if (comboMidiRxEnable->currentText() == "Enabled")
-	    m_pMidi->setRxStatus(labelDeviceName->text(), true);
-	else
-	    m_pMidi->setRxStatus(labelDeviceName->text(), false);
-	if (comboMidiTxEnable->currentText() == "Enabled")
-	    m_pMidi->setTxStatus(labelDeviceName->text(), true);
-	else
-	    m_pMidi->setTxStatus(labelDeviceName->text(), false);
-	
+	if (comboMidiRxEnable->currentText() == "Enabled") {
+	    //m_pMidi->setRxStatus(labelDeviceName->text(), true);
+	} else {
+	   // m_pMidi->setRxStatus(labelDeviceName->text(), false);
+	}
+	if (comboMidiTxEnable->currentText() == "Enabled") {
+	    //m_pMidi->setTxStatus(labelDeviceName->text(), true);
+	} else {
+	    //m_pMidi->setTxStatus(labelDeviceName->text(), false);
+	}
 }
 
 void DlgPrefMidiDevice::saveSettings(QString device, QString Rx, QString Tx) {
 	// Save current settings to the configobject
 	m_pDeviceSettings->set(ConfigKey("[" + device + "]","RxEnable"), Rx);
 	m_pDeviceSettings->set(ConfigKey("[" + device + "]","TxEnable"), Tx);
+	
+	qDebug() << "Saved settings for" << device << Rx << Tx;	
 }
 
 void DlgPrefMidiDevice::readSettings() {
 	// Read in settings from the configobject for the current device
         if (m_pDeviceSettings->getValueString(ConfigKey("[" + labelDeviceName->text() + "]","RxEnable")) == "Enabled") {
         	comboMidiRxEnable->setCurrentIndex(1);
-        	m_pMidi->setRxStatus(labelDeviceName->text(), true);
+        	//m_pMidi->setRxStatus(labelDeviceName->text(), true);
         } else {
         	comboMidiRxEnable->setCurrentIndex(0);
-        	m_pMidi->setRxStatus(labelDeviceName->text(), false);
+        	//m_pMidi->setRxStatus(labelDeviceName->text(), false);
         }
         if (m_pDeviceSettings->getValueString(ConfigKey("[" + labelDeviceName->text() + "]","TxEnable")) == "Enabled") {
         	comboMidiTxEnable->setCurrentIndex(1);
-        	m_pMidi->setTxStatus(labelDeviceName->text(), true);
+        	//m_pMidi->setTxStatus(labelDeviceName->text(), true);
         } else {
         	comboMidiTxEnable->setCurrentIndex(0);
-        	m_pMidi->setTxStatus(labelDeviceName->text(), false);
+        	//m_pMidi->setTxStatus(labelDeviceName->text(), false);
         }
 }
 
@@ -181,9 +197,9 @@
 void DlgPrefMidiDevice::presetAvailable(QString deviceName) {
 	// Is there a preset available
     QString qConfigPath = m_pConfig->getConfigPath();
-	QStringList * midiConfigList = m_pMidi->getConfigList(qConfigPath.append("midi/"));
+	QStringList midiConfigList = m_pMidiDeviceManager->getConfigList(qConfigPath.append("midi/"));
 
-	for (QStringList::Iterator it = midiConfigList->begin(); it != midiConfigList->end(); ++it ) {
+	for (QStringList::Iterator it = midiConfigList.begin(); it != midiConfigList.end(); ++it ) {
 		// For each xml preset, open the preset
 		QString presetPath = m_pConfig->getValueString(ConfigKey("[Config]","Path")).append("midi/").append(*it);
 		QDomElement doc = WWidget::openXMLFile(presetPath, "MixxxMIDIPreset");
@@ -223,6 +239,8 @@
 	labelPresetAvailable->setText("");
     comboMidiRxEnable->setEnabled(false);
     comboMidiTxEnable->setEnabled(false);
+    
+    m_pMidiDeviceManager->setupDevices();
 }
 
 /* TODO:
Index: dlgprefmididevice.h
===================================================================
--- dlgprefmididevice.h	(revision 2449)
+++ dlgprefmididevice.h	(working copy)
@@ -21,12 +21,12 @@
 #include "ui_dlgprefmididevicedlg.h"
 #include "configobject.h"
 
-class MidiObject;
+class MidiDeviceManager;
 
 class DlgPrefMidiDevice : public QWidget, public Ui::DlgPrefMidiDeviceDlg  {
     Q_OBJECT
 public:
-    DlgPrefMidiDevice(QWidget *parent, MidiObject* midi, ConfigObject<ConfigValue> *pConfig);
+    DlgPrefMidiDevice(QWidget *parent, MidiDeviceManager* midi, ConfigObject<ConfigValue> *pConfig);
     ~DlgPrefMidiDevice();
 
 public slots:
@@ -42,11 +42,10 @@
 	bool deviceEnabled(); // Is the currently selected device enabled?
 	void presetAvailable(QString deviceName); // Is there a preset available
 	void setupDevices();
-        bool eventFilter(QObject * o, QEvent * e);
-    MidiObject *m_pMidi;
+    MidiDeviceManager *m_pMidiDeviceManager;
+    bool eventFilter(QObject * o, QEvent * e);
     ConfigObject<ConfigValue> *m_pDeviceSettings;
     ConfigObject<ConfigValue> *m_pConfig;
-    ConfigObject<ConfigValueMidi> *m_pMidiConfig;
 };
 
 #endif /*DLGPREFMIDIDEVICE_H_*/
Index: dlgprefmidibindings.cpp
===================================================================
--- dlgprefmidibindings.cpp	(revision 2449)
+++ dlgprefmidibindings.cpp	(working copy)
@@ -18,7 +18,12 @@
 #include <QDebug>
 #include "dlgprefmidibindings.h"
 #include "wwidget.h"
+#include "defs.h"
 #include "configobject.h"
+#include "midiprocessor.h"
+#include "midicontrolprocessor.h"
+#include "mididevicemanager.h"
+#include "mididevice.h"
 
 #ifdef __SCRIPT__
 #include "script/midiscriptengine.h"
@@ -38,12 +43,12 @@
     return "0x" + QString("0" + QString::number(numberStr.toUShort(), 16).toUpper()).right(2);
 }
 
-DlgPrefMidiBindings::DlgPrefMidiBindings(QWidget *parent, MidiObject *midi, ConfigObject<ConfigValue> *pConfig) :  QWidget(parent), Ui::DlgPrefMidiBindingsDlg() {
+DlgPrefMidiBindings::DlgPrefMidiBindings(QWidget *parent, MidiDeviceManager *midi, ConfigObject<ConfigValue> *pConfig) :  QWidget(parent), Ui::DlgPrefMidiBindingsDlg() {
     setupUi(this);
     m_pConfig = pConfig;
     singleLearning = false;
     groupLearning = false;
-    m_pMidi = midi;
+    m_pMidiDeviceManager = midi;
 
     // Connect buttons to slots
     connect(btnSingleLearn, SIGNAL(clicked()), this, SLOT(slotSingleLearnToggle()));
@@ -68,7 +73,6 @@
     // Try to read in the current XML bindings file, or create one if nothing is available
     loadPreset(BINDINGS_PATH);
     applyPreset();
-    m_pMidi->disableMidiLearn();
 }
 
 DlgPrefMidiBindings::~DlgPrefMidiBindings() {
@@ -218,12 +222,19 @@
         m_pMidiConfig = new ConfigObject<ConfigValueMidi>(controller.namedItem("controls"));
 
         qDebug() << "Processing MIDI Output Bindings for" << deviceId;
-        MidiLedHandler::createHandlers(controller.namedItem("outputs").firstChild(), m_pMidi, deviceId);
+        MidiLedHandler::createHandlers(controller.namedItem("outputs").firstChild(), 
+        							m_pMidiDeviceManager->getPrimaryMidiDevice(), deviceId);
 
         // Next device
         controller = controller.nextSiblingElement("controller");
     }
-    m_pMidi->setMidiConfig(m_pMidiConfig);
+    //FIXME: hack for a single device
+    //FIXME: dangerous cast, should use dynamic_cast
+    if (m_pMidiDeviceManager->getPrimaryMidiDevice())
+    {
+  	    qDebug() << "DlgPrefMidiBindings: Applying new MIDI config/preset...";
+	    ((MidiControlProcessor*)m_pMidiDeviceManager->getPrimaryMidiDevice()->getMidiProcessor())->setMidiConfig(m_pMidiConfig);
+    }
 }
 
 /* clearPreset()
@@ -266,8 +277,8 @@
     /* User has pressed OK, so write the controls to the DOM, reload the MIDI
      * bindings, and save the default XML file. */
     savePreset(BINDINGS_PATH);
+    m_pMidiDeviceManager->disableMidiLearn();
     applyPreset();
-    m_pMidi->disableMidiLearn();
 }
 
 /*
@@ -375,13 +386,13 @@
     singleLearning = !singleLearning;
     if (singleLearning) {
         // Enable MIDI Hook
-        m_pMidi->enableMidiLearn(this);
+        m_pMidiDeviceManager->enableMidiLearn(this);
         labelStatus->setText("Single MIDI Learn: waiting...");
         // Can't do group learning while single learning
         btnGroupLearn->setEnabled(false);
     } else {
         // Disable MIDI Hook
-        m_pMidi->disableMidiLearn();
+        m_pMidiDeviceManager->disableMidiLearn();
         labelStatus->setText("Single MIDI Learn disabled");
         btnGroupLearn->setEnabled(true);
     }
@@ -394,13 +405,13 @@
     groupLearning = !groupLearning;
     if (groupLearning) {
         // Enable MIDI Hook
-        m_pMidi->enableMidiLearn(this);
+        m_pMidiDeviceManager->enableMidiLearn(this);
         labelStatus->setText("Group MIDI Learn: waiting...");
         // Can't do group learning while single learning
         btnSingleLearn->setEnabled(false);
     } else {
         // Disable MIDI Hook
-        m_pMidi->disableMidiLearn();
+        m_pMidiDeviceManager->disableMidiLearn();
         labelStatus->setText("Group MIDI Learn disabled");
         btnSingleLearn->setEnabled(true);
     }
@@ -475,7 +486,7 @@
         int off = (unsigned char) tblOutputBindings->item(y,7)->text().trimmed().toUShort(&ok, 0);
         if (!ok) { off = 0x00; }
 
-        m_pMidi->sendShortMsg(status, midino, btnTestOutputBinding->isChecked()? on : off , device);
+        m_pMidiDeviceManager->getPrimaryMidiDevice()->sendShortMsg(status, midino, btnTestOutputBinding->isChecked()? on : off);
     }
     labelOutputStatus->setText( btnTestOutputBinding->isChecked()? outputType + " on" : outputType + " off" );
 // TODO: create "outputCycleNext" checkbox which when checked will move to the next row when an off event happens
@@ -538,8 +549,12 @@
 
     QStringList selectionList;
 
-    // Try to load values, when that fails pick up last entry values from existing table where present.
-    selectionList = QStringList(m_pMidi->getOpenDevices());
+    // Try to load values, when that fails pick up last entry values from existing table where present.   
+    QList<MidiDevice*> deviceList = m_pMidiDeviceManager->getDeviceList();
+    for (int i = 0; i < deviceList.count(); i++) {
+    	selectionList.append(deviceList.at(i)->getName());
+    }    
+    
     if (selectionList.size() == 0 && tblBindings->rowCount() > 0) { selectionList.append(tblBindings->item(tblBindings->rowCount() - 1,2)->text()); }
     QString device = QInputDialog::getItem(this, tr("1/6 Select Device"), tr("Select a device to control"), selectionList, 0, true, &ok);
     if (!ok) return;
@@ -580,7 +595,11 @@
     bool ok = true;
 
     QStringList selectionList;
-    selectionList = QStringList(m_pMidi->getOpenDevices());
+    QList<MidiDevice*> deviceList = m_pMidiDeviceManager->getDeviceList();
+    for (int i = 0; i < deviceList.count(); i++) {
+    	selectionList.append(deviceList.at(i)->getName());
+    }
+    
     if (selectionList.size() == 0 && tblBindings->rowCount() > 0) { selectionList.append(tblBindings->item(tblBindings->rowCount() - 1,2)->text()); }
     QString device = QInputDialog::getItem(this, tr("Select Device"), tr("Select a device to control"), selectionList, 0, true, &ok);
     if (!ok) return;
Index: dlgprefmidibindings.h
===================================================================
--- dlgprefmidibindings.h	(revision 2449)
+++ dlgprefmidibindings.h	(working copy)
@@ -21,12 +21,13 @@
 #include "ui_dlgprefmidibindingsdlg.h"
 #include "configobject.h"
 #include "midiledhandler.h"
-#include "midiobject.h"
+#include "midilearnlistener.h"
+class MidiDeviceManager;
 
-class DlgPrefMidiBindings : public QWidget, public Ui::DlgPrefMidiBindingsDlg  {
+class DlgPrefMidiBindings : public virtual QWidget, public virtual Ui::DlgPrefMidiBindingsDlg {
     Q_OBJECT
 public:
-    DlgPrefMidiBindings(QWidget *parent, MidiObject *midi, ConfigObject<ConfigValue> *pConfig);
+    DlgPrefMidiBindings(QWidget *parent, MidiDeviceManager *midi, ConfigObject<ConfigValue> *pConfig);
     ~DlgPrefMidiBindings();
 
 
@@ -42,9 +43,10 @@
     void slotAddBinding();
 //    void slotChangeBinding();
 //    void slotAdvancedOptions();
-    void singleLearn(ConfigValueMidi *value, QString device);
-    void groupLearn(ConfigValueMidi *value, QString device);
-
+    	
+    	
+    void singleLearn(ConfigValueMidi *value, QString device) ;
+   	void groupLearn(ConfigValueMidi *value, QString device);
     void slotTestOutputBinding();
     void slotClearOutputBindings();
     void slotAddOutputBinding();
@@ -68,7 +70,7 @@
 	bool groupLearning;
 	int currentGroupRow;
 	QDomElement m_pBindings;
-    MidiObject *m_pMidi;
+    MidiDeviceManager *m_pMidiDeviceManager;
     ConfigObject<ConfigValue> *m_pConfig;
     ConfigObject<ConfigValueMidi> *m_pMidiConfig;
 };
Index: dlgpreferences.cpp
===================================================================
--- dlgpreferences.cpp	(revision 2449)
+++ dlgpreferences.cpp	(working copy)
@@ -37,7 +37,7 @@
 #include "dlgprefrecord.h"
 #include "mixxx.h"
 #include "track.h"
-#include "midiobject.h"
+#include "mididevicemanager.h"
 #include <QTabWidget>
 
 #include <QTabBar>
@@ -47,7 +47,7 @@
 
 DlgPreferences::DlgPreferences(MixxxApp * mixxx, MixxxView * view,
                                SoundManager * soundman, Track *track,
-                               MidiObject * midi, ConfigObject<ConfigValue> * _config) :  QDialog(), Ui::DlgPreferencesDlg()
+                               MidiDeviceManager * midi, ConfigObject<ConfigValue> * _config) :  QDialog(), Ui::DlgPreferencesDlg()
 {
     m_pMixxx = mixxx;
 
@@ -62,7 +62,6 @@
 
     // Construct widgets for use in tabs
     wsound = new DlgPrefSound(this, soundman, config);
- //   wmidi  = new DlgPrefMidi(this, config);
     wmidiDevice  = new DlgPrefMidiDevice(this, midi, config);
     wmidiBindings  = new DlgPrefMidiBindings(this, midi, config);
     wplaylist = new DlgPrefPlaylist(this, config);
@@ -85,7 +84,6 @@
     }
 
     pagesWidget->addWidget(wsound);
-    //pagesWidget->addWidget(wmidi);
     pagesWidget->addWidget(wmidiDevice);
     pagesWidget->addWidget(wmidiBindings);
     pagesWidget->addWidget(wplaylist);
@@ -107,7 +105,6 @@
     // Connections
     connect(this, SIGNAL(showDlg()), this,      SLOT(slotUpdate()));
     connect(this, SIGNAL(showDlg()), wsound,    SLOT(slotUpdate()));
-//    connect(this, SIGNAL(showDlg()), wmidi,     SLOT(slotUpdate()));
     connect(this, SIGNAL(showDlg()), wmidiDevice,	SLOT(slotUpdate()));
     connect(this, SIGNAL(showDlg()), wmidiBindings, SLOT(slotUpdate()));
     connect(this, SIGNAL(showDlg()), wplaylist, SLOT(slotUpdate()));
@@ -131,7 +128,6 @@
                                                                                  //connect for wsound...
 #endif
     connect(buttonBox, SIGNAL(accepted()), wsound,    SLOT(slotApply()));
-//    connect(buttonBox, SIGNAL(accepted()), wmidi,     SLOT(slotApply()));
     connect(buttonBox, SIGNAL(accepted()), wmidiDevice,	SLOT(slotApply()));
     connect(buttonBox, SIGNAL(accepted()), wmidiBindings,	SLOT(slotApply()));
     connect(buttonBox, SIGNAL(accepted()), wplaylist, SLOT(slotApply()));
@@ -163,13 +159,7 @@
     soundButton->setText(tr("Sound Hardware"));
     soundButton->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
     soundButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
-/*
-    QListWidgetItem * midiButton = new QListWidgetItem(contentsWidget);
-    midiButton->setIcon(QIcon(":/images/preferences/controllers.png"));
-    midiButton->setText(tr("Input Controllers"));
-    midiButton->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
-    midiButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
-*/
+
     QListWidgetItem * midiDeviceButton = new QListWidgetItem(contentsWidget);
     midiDeviceButton->setIcon(QIcon(":/images/preferences/controllers.png"));
     midiDeviceButton->setText(tr("MIDI Device Selection"));
Index: dlgpreferences.h
===================================================================
--- dlgpreferences.h	(revision 2449)
+++ dlgpreferences.h	(working copy)
@@ -47,7 +47,7 @@
 class DlgPrefVinyl;
 class DlgPrefShoutcast;
 class PowerMate;
-class MidiObject;
+class MidiDeviceManager;
 
 /**
   *@author Tue & Ken Haste Andersen
@@ -58,7 +58,7 @@
     Q_OBJECT
 public:
     DlgPreferences(MixxxApp *mixxx, MixxxView *view, SoundManager *soundman,
-    		Track *track, MidiObject * midi, ConfigObject<ConfigValue> *config);
+    		Track *track, MidiDeviceManager *midi, ConfigObject<ConfigValue> *config);
     ~DlgPreferences();
     void createIcons();
 public slots:
Index: mixxx.cpp
===================================================================
--- mixxx.cpp	(revision 2449)
+++ mixxx.cpp	(working copy)
@@ -42,6 +42,8 @@
 #include "log.h"
 #include "dlgabout.h"
 
+#include "mididevicemanager.h"
+
 #include "soundmanager.h"
 #include "defs_urls.h"
 #include "defs_audiofiles.h"
@@ -97,7 +99,7 @@
     soundmanager = 0;
     m_pTrack = 0;
     prefDlg = 0;
-    midi = 0;
+    m_pMidiDeviceManager = 0;
 
     // Read the config file from home directory
     config = new ConfigObject<ConfigValue>(QDir::homePath().append("/").append(SETTINGS_FILE));
@@ -311,11 +313,13 @@
     ControlObject::getControl(ConfigKey("[Channel2]","TrackEndMode"))->queueFromThread(config->getValueString(ConfigKey("[Controls]","TrackEndModeCh2")).toDouble());
 
     // Initialise midi
-    MidiDeviceHandler * midiHandler = new MidiDeviceHandler();
-    midi = midiHandler->getMidiPtr();
+    m_pMidiDeviceManager = new MidiDeviceManager(config);
+    //TODO: Try to open MIDI devices?
+    m_pMidiDeviceManager->queryDevices();
+    m_pMidiDeviceManager->setupDevices();
 
     // Initialize preference dialog
-    prefDlg = new DlgPreferences(this, view, soundmanager, m_pTrack, midi, config);
+    prefDlg = new DlgPreferences(this, view, soundmanager, m_pTrack, m_pMidiDeviceManager, config);
     prefDlg->setHidden(true);
 
 #ifdef __LADSPA__
@@ -426,6 +430,9 @@
     config->set(ConfigKey("[Controls]","TrackEndModeCh1"), ConfigValue((int)ControlObject::getControl(ConfigKey("[Channel1]","TrackEndMode"))->get()));
     config->set(ConfigKey("[Controls]","TrackEndModeCh2"), ConfigValue((int)ControlObject::getControl(ConfigKey("[Channel2]","TrackEndMode"))->get()));
 
+	qDebug() << "delete MidiDeviceManager";
+	delete m_pMidiDeviceManager;
+
     qDebug() << "delete soundmanager, " << qTime.elapsed();
     delete soundmanager;
     qDebug() << "delete master, " << qTime.elapsed();
Index: mixxx.h
===================================================================
--- mixxx.h	(revision 2449)
+++ mixxx.h	(working copy)
@@ -74,6 +74,7 @@
 class BpmDetector;
 class QSplashScreen;
 class ScriptEngine;
+class MidiDeviceManager;
 
 /**
   * This Class is the base class for Mixxx. It sets up the main
@@ -160,7 +161,7 @@
     EngineChannel *channel1, *channel2;
     EngineMaster *master;
     SoundManager *soundmanager;
-    MidiObject *midi;
+	MidiDeviceManager *m_pMidiDeviceManager;
     ControlObject *control;
     ConfigObject<ConfigValue> *config;
     /** Pointer to active midi configuration */
Index: midiledhandler.cpp
===================================================================
--- midiledhandler.cpp	(revision 2449)
+++ midiledhandler.cpp	(working copy)
@@ -1,3 +1,4 @@
+#include "mididevice.h"
 #include "midiledhandler.h"
 #include "wwidget.h"
 //Added by qt3to4:
@@ -6,7 +7,7 @@
 
 Q3PtrList<MidiLedHandler> MidiLedHandler::allhandlers = Q3PtrList<MidiLedHandler>();
 
-MidiLedHandler::MidiLedHandler(QString group, QString key, MidiObject * midi, double min,
+MidiLedHandler::MidiLedHandler(QString group, QString key, MidiDevice * midi, double min,
                                double max, unsigned char status, unsigned char midino, QString device, unsigned char on, unsigned char off)
     : m_min(min), m_max(max), m_midi(midi), m_status(status), m_midino(midino), m_device(device), m_on(on), m_off(off) {
 
@@ -35,12 +36,12 @@
 	lastStatus=m_byte2;
  	if (m_byte2 != 0xff) {
 		// qDebug() << "MIDI bytes:" << m_status << ", " << m_midino << ", " << m_byte2 ;
-		m_midi->sendShortMsg(m_status, m_midino, m_byte2, m_device);
+		m_midi->sendShortMsg(m_status, m_midino, m_byte2);
 	}
     }
 }
 
-void MidiLedHandler::createHandlers(QDomNode node, MidiObject * midi, QString device) {
+void MidiLedHandler::createHandlers(QDomNode node, MidiDevice * midi, QString device) {
     if (!node.isNull() && node.isElement()) {
         QDomNode light = node;
         while (!light.isNull()) {
Index: midiledhandler.h
===================================================================
--- midiledhandler.h	(revision 2449)
+++ midiledhandler.h	(working copy)
@@ -5,7 +5,7 @@
 #define MIDILEDHANDLER_H
 
 #include "controlobject.h"
-#include "midiobject.h"
+class MidiDevice;
 
 #include <q3ptrlist.h>
 
@@ -13,11 +13,11 @@
 {
     Q_OBJECT
 public:
-	MidiLedHandler(QString group, QString key, MidiObject* midi, double min, double max,
+	MidiLedHandler(QString group, QString key, MidiDevice* midi, double min, double max,
 		unsigned char status, unsigned char midino, QString device, unsigned char on, unsigned char off);
     ~MidiLedHandler();
 
-	static void createHandlers(QDomNode node, MidiObject* midi, QString device);
+	static void createHandlers(QDomNode node, MidiDevice* midi, QString device);
 	static void destroyHandlers();
 	static Q3PtrList<MidiLedHandler> allhandlers;
 
@@ -25,7 +25,7 @@
 	void controlChanged(double value);
 
 private:
-	MidiObject* m_midi;
+	MidiDevice* m_midi;
 	double m_min;
 	double m_max;
 	ControlObject* m_cobj;
