module.exports = {
  link: function(library, destinations, logger) {
    var self = this;

    logger = logger || console;

    if (!Array.isArray(destinations)) {
      destinations = [destinations];
    }

    if (library.contract_name == null) {
      throw new Error("Cannot link a library with no name.");
    }

    if (library.address == null) {
      throw new Error("Cannot link library: " + library.contract_name + " has no address. Has it been deployed?");
    }

    destinations.forEach(function(destination) {
      // Don't link if result will have no effect.
      if (destination.links[library.contract_name] == library.address) return;

      logger.log("Linking " + library.contract_name + " to " + destination.contract_name);
      destination.link(library);
    });
  },

  autolink: function(contract, available_contracts, logger) {
    // Abstract contract passed.
    if (contract.binary == null) return;

    var self = this;
    var regex = /__[^_]+_+/g;

    logger = logger || console;

    var unlinked_libraries = contract.unlinked_binary.match(regex);

    // Nothing to link.
    if (unlinked_libraries == null) return;

    if (unlinked_libraries.length == 0) {
      throw new Error("Cannot auto link " + contract.contract_name + "; " + contract.contract_name + " has no library dependencies.")
    }

    unlinked_libraries = unlinked_libraries.map(function(name) {
      // Remove underscores
      return name.replace(/_/g, "");
    }).sort().filter(function(name, index, arr) {
      // Remove duplicates
      if (index + 1 >= arr.length) {
        return true;
      }

      return name != arr[index + 1];
    });

    unlinked_libraries.forEach(function(name) {
      var library = available_contracts[name];

      if (library == null) {
        throw new Error("Cannot auto link " + contract.contract_name + "; " + contract.contract_name + " unknown dependency " + name + ".")
      }

      self.link(library, contract, logger);
    });
  }
};

@@ -319,35 +319,274 @@
     
-if (library.address == null
+var hasAddress = false;%0A%0A    // Abstractions; don't want to use .address directly because it will throw.%0A    if (typeof library.isDeployed) %7B%0A      hasAddress = library.isDeployed();%0A    %7D else %7B%0A      hasAddress = library.address != null;%0A    %7D%0A%0A    if (!hasAddress
 ) %7B%0A
@@ -881,24 +881,167 @@
 ess) return;
+    // already linked to same address%0A      if (destination.unlinked_binary.indexOf(library.contract_name) %3C 0) return; // no linkage available
 %0A%0A      logg
@@ -1169,16 +1169,19 @@
 %0A  %7D,%0A%0A 
+ //
  autolin
@@ -1234,16 +1234,19 @@
 ger) %7B%0A 
+ //
    // Ab
@@ -1270,16 +1270,19 @@
 assed.%0A 
+ //
    if (c
@@ -1313,18 +1313,25 @@
 return;%0A
-%0A
  
+ //%0A  //
    var s
@@ -1344,18 +1344,21 @@
 this;%0A  
+//
   
+ 
 var rege
@@ -1375,18 +1375,25 @@
 %5D+_+/g;%0A
-%0A
  
+ //%0A  //
    logge
@@ -1415,18 +1415,25 @@
 onsole;%0A
-%0A
  
+ //%0A  //
    var u
@@ -1491,18 +1491,25 @@
 regex);%0A
-%0A
  
+ //%0A  //
    // No
@@ -1521,26 +1521,29 @@
  to link.%0A  
+//
   
+ 
 if (unlinked
@@ -1570,18 +1570,25 @@
 return;%0A
-%0A
  
+ //%0A  //
    if (u
@@ -1617,24 +1617,27 @@
 th == 0) %7B%0A 
+ //
      throw n
@@ -1758,23 +1758,33 @@
 ies.%22)%0A 
+ //
    %7D%0A
-%0A
  
+ //%0A  //
    unlin
@@ -1836,24 +1836,27 @@
 on(name) %7B%0A 
+ //
      // Remo
@@ -1867,24 +1867,27 @@
 nderscores%0A 
+ //
      return 
@@ -1907,24 +1907,27 @@
 /_/g, %22%22);%0A 
+ //
    %7D).sort()
@@ -1965,20 +1965,23 @@
 rr) %7B%0A  
+//
     
+ 
 // Remov
@@ -1994,16 +1994,19 @@
 icates%0A 
+ //
      if 
@@ -2030,24 +2030,27 @@
 .length) %7B%0A 
+ //
        retur
@@ -2058,25 +2058,35 @@
  true;%0A 
+ //
      %7D%0A
-%0A
  
+ //%0A  //
      ret
@@ -2118,17 +2118,27 @@
 %5D;%0A 
+ //
    %7D);%0A
-%0A
  
+ //%0A  //
    u
@@ -2177,24 +2177,27 @@
 on(name) %7B%0A 
+ //
      var lib
@@ -2230,18 +2230,25 @@
 %5Bname%5D;%0A
-%0A
  
+ //%0A  //
      if 
@@ -2264,24 +2264,27 @@
 == null) %7B%0A 
+ //
        throw
@@ -2415,17 +2415,27 @@
 %22)%0A 
+ //
      %7D%0A
-%0A
  
+ //%0A  //
     
@@ -2474,22 +2474,25 @@
 gger);%0A 
+ //
    %7D);%0A 
  %7D%0A%7D;%0A
@@ -2485,14 +2485,17 @@
    %7D);%0A 
+ //
  %7D%0A%7D;%0A

Remove autolink; also, add extra checks to ensure we're linking the right thing.