var upnp = require("./lib/upnp.js");
var http = require('http');
var _ = require('underscore');
var url = require('url');
var Ds = require('./ds.js').Ds;
var responseParsers = require('./responseparsers.js');
var controlPoint = new upnp.ControlPoint();
var devices = {};

const playlistService = 'urn:av-openhome-org:service:Playlist:1';
const linnSources = 'urn:linn-co-uk:device:Source:1';

function parseUuid (usn, st) {
    return (/uuid:(.*)?::.*/).exec(usn)[1];
}

function toDevice(result, callback) {
    var ds = new Ds(result.root.URLBase);
    ds.getSources(function (err, results) {
        if (err) {
            callback(err);
        } else {
            device = {
                name: result.root.device.friendlyName,
                urlRoot: result.root.URLBase,
                serviceList: result.root.device.serviceList.service,
                sourceList: results,
                ds: ds
            };
            if (result.root.device.iconList) {
                device.icon = result.root.device.iconList.icon;
            }
            callback(null, device); 
        }
    });
}

function processDevice(location, callback) {
    console.log(location);
    http.get(location, responseParsers.xml(toDevice, callback)).on('error', callback);
}

exports.getDevices = function getDevices() {
    return _.keys(devices);
};
exports.getDevice = function getDevice(uuid) {
    return devices[uuid];
};
exports.subscribe = function subscribe(device, serviceType) {
    var urlRoot = url.parse(device.urlRoot);
    var service = _.findWhere(device.serviceList, { serviceType : serviceType });
    if (service) {
        upnp.subscribe(urlRoot.hostname, urlRoot.port, service.eventSubURL);
    }
};

controlPoint.on("DeviceAvailable", function onDeviceAvailable(res) {
    if (res.nt === playlistService)
    {
        var uuid = parseUuid(res.usn, res.nt);
        processDevice(res.location, function makeDeviceAvailable(err, device) {
            if (err) {
                console.log("Problem processing device: " + err);
            } else {
                devices[uuid] = device;
            }
        });
    }
});

controlPoint.on("DeviceUnavailable", function onDeviceUnavailable(res) {
    if (res.nt === playlistService)
    {
        var uuid = parseUuid(res.usn, res.nt);
        if (devices[uuid]) {
            var device = devices[uuid];
            delete devices[uuid];
        }
    }
});

controlPoint.on("DeviceFound", function onDeviceFound(res) {
    var uuid = parseUuid(res.usn, res.st);
    processDevice(res.location, function makeDeviceAvailable(err, device) {
        if (err) {
            console.log("Problem processing device: " + err);
        } else {
            devices[uuid] = device;
        }
    });
});

controlPoint.search(linnSources);
@@ -460,24 +460,78 @@
 usn)%5B1%5D;%0A%7D%0A%0A
+function toDeviceUsingLocation(location) %7B%0A    return 
 function toD
@@ -552,24 +552,28 @@
 callback) %7B%0A
+    
     var ds =
@@ -584,30 +584,23 @@
  Ds(
-result.root.URLBase);%0A
+location);%0A    
     
@@ -639,32 +639,36 @@
 ults) %7B%0A        
+    
 if (err) %7B%0A     
@@ -666,32 +666,36 @@
 ) %7B%0A            
+ 
+   
 callback(err);%0A 
@@ -693,32 +693,36 @@
 k(err);%0A        
+    
 %7D else %7B%0A       
@@ -722,24 +722,28 @@
             
+  
+  
 device = %7B%0A 
@@ -741,16 +741,20 @@
 ice = %7B%0A
+    
         
@@ -816,16 +816,20 @@
         
+  
+  
 urlRoot:
@@ -833,29 +833,22 @@
 ot: 
-result.root.URLBase,%0A
+location,%0A    
     
@@ -928,16 +928,20 @@
         
+    
 sourceLi
@@ -969,16 +969,20 @@
         
+   
+ 
 ds: ds%0A 
@@ -992,19 +992,27 @@
         
-%7D;%0A
+    %7D;%0A    
         
@@ -1070,70 +1070,462 @@
     
-device.icon = result.root.device.iconList.icon;%0A            %7D%0A
+    var icon = _.isArray(result.root.device.iconList.icon) ? result.root.device.iconList.icon%5B0%5D : result.root.device.iconList.icon;%0A                    device.icon = %7B%0A                        mimetype: icon.mimetype,%0A                        width: icon.width,%0A                        height: icon.height,%0A                        depth: icon.depth,%0A                        url: url.resolve(location, icon.url)%0A                    %7D%0A                %7D%0A    
     
@@ -1565,26 +1565,40 @@
         
-%7D%0A
+    %7D%0A   
     
+ 
 %7D);%0A
+    %7D%0A
 %7D%0A%0Afunct
@@ -1715,16 +1715,39 @@
 toDevice
+UsingLocation(location)
 , callba

Use discovered device location instead of URLBase in service definition