diff --git a/src/nlsr_adl.cpp b/src/nlsr_adl.cpp
new file mode 100644
index 0000000..eaf0699
--- /dev/null
+++ b/src/nlsr_adl.cpp
@@ -0,0 +1,264 @@
+#include<iostream>
+#include<algorithm>
+
+#include "nlsr_adl.hpp"
+#include "nlsr_adjacent.hpp"
+#include "nlsr.hpp"
+
+Adl::Adl(){
+}
+
+Adl::~Adl(){
+
+}
+
+static bool
+adjacent_compare(Adjacent& adj1, Adjacent& adj2){
+	return adj1.getAdjacentName()==adj2.getAdjacentName();
+}
+
+int
+Adl::insert(Adjacent& adj){
+	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
+								adjList.end(),	
+   								bind(&adjacent_compare, _1, adj));
+	if ( it != adjList.end() ){
+		return -1;
+	}
+	adjList.push_back(adj);
+	return 0;
+}
+
+void 
+Adl::addAdjacentsFromAdl(Adl& adl)
+{
+	for(std::list<Adjacent >::iterator it=adl.getAdjList().begin();
+	                                             it!=adl.getAdjList().end(); ++it)
+	{
+		insert((*it));
+	}
+}
+
+int
+Adl::updateAdjacentStatus(string adjName, int s){
+	Adjacent adj(adjName);
+	
+	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
+								adjList.end(),	
+   								bind(&adjacent_compare, _1, adj));
+
+	if( it == adjList.end()){
+		return -1;
+	}
+
+	(*it).setStatus(s);
+	return 0;
+	
+
+}
+
+Adjacent 
+Adl::getAdjacent(string adjName)
+{
+	Adjacent adj(adjName);
+	
+	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
+								adjList.end(),	
+   								bind(&adjacent_compare, _1, adj));
+
+	if( it != adjList.end()){
+		return (*it);
+	}
+
+	return adj;
+}
+
+
+bool 
+Adl::isAdlEqual(Adl &adl)
+{
+	if ( getAdlSize() != adl.getAdlSize() )
+	{
+		return false;
+	}
+
+	adjList.sort(adjacent_compare);	
+	adl.getAdjList().sort(adjacent_compare);
+	int equalAdjCount=0;
+
+	std::list< Adjacent > adjList2=adl.getAdjList();
+
+	std::list<Adjacent>::iterator it1;
+	std::list<Adjacent>::iterator it2;
+	for(it1=adjList.begin() , it2=adjList2.begin() ; 
+	                                              it1!=adjList.end(); it1++,it2++)
+	{
+		if ( !(*it1).isAdjacentEqual((*it2)) )
+		{
+			break;
+		}
+		equalAdjCount++;
+	}
+
+	return equalAdjCount==getAdlSize();
+}
+
+
+int 
+Adl::updateAdjacentLinkCost(string adjName, double lc){
+	Adjacent adj(adjName);
+	
+	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
+								adjList.end(),	
+   								bind(&adjacent_compare, _1, adj));
+
+	if( it == adjList.end()){
+		return -1;
+	}
+
+	(*it).setLinkCost(lc);
+	return 0;
+
+}
+
+bool 
+Adl::isNeighbor(string adjName){
+	Adjacent adj(adjName);
+	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
+								adjList.end(),	
+   								bind(&adjacent_compare, _1, adj));
+
+	if( it == adjList.end()){
+		return false;
+	}
+
+	return true;
+}
+
+void 
+Adl::incrementTimedOutInterestCount(string& neighbor){
+	Adjacent adj(neighbor);
+	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
+								adjList.end(),	
+   								bind(&adjacent_compare, _1, adj));
+
+	if( it == adjList.end()){
+		return ;
+	}
+
+	(*it).setInterestTimedOutNo((*it).getInterestTimedOutNo()+1);
+
+}
+
+void 
+Adl::setTimedOutInterestCount(string& neighbor, int count){
+	Adjacent adj(neighbor);
+	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
+								adjList.end(),	
+   								bind(&adjacent_compare, _1, adj));
+
+	if( it != adjList.end()){
+		(*it).setInterestTimedOutNo(count);
+	}
+}
+
+int
+Adl::getTimedOutInterestCount(string& neighbor)
+{
+	Adjacent adj(neighbor);
+	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
+								adjList.end(),	
+   								bind(&adjacent_compare, _1, adj));
+
+	if( it == adjList.end()){
+		return -1;
+	}
+
+	return (*it).getInterestTimedOutNo();
+}
+
+int 
+Adl::getStatusOfNeighbor(string& neighbor)
+{
+	Adjacent adj(neighbor);
+	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
+								adjList.end(),	
+   								bind(&adjacent_compare, _1, adj));
+
+	if( it == adjList.end()){
+		return -1;
+	}
+
+	return (*it).getStatus();
+}
+
+void
+Adl::setStatusOfNeighbor(string& neighbor, int status)
+{
+	Adjacent adj(neighbor);
+	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
+								adjList.end(),	
+   								bind(&adjacent_compare, _1, adj));
+
+	if( it != adjList.end()){
+		(*it).setStatus(status);
+	}
+}
+
+std::list<Adjacent>& 
+Adl::getAdjList(){
+	return adjList;
+}
+
+bool
+Adl::isAdjLsaBuildable(nlsr& pnlsr)
+{
+	int nbrCount=0;
+	for( std::list<Adjacent>::iterator it=adjList.begin(); 
+	                                                   it!= adjList.end() ; it++)
+	{
+		if ( ((*it).getStatus() == 1 ) )
+		{
+			nbrCount++;
+		}
+		else
+		{
+			if ( (*it).getInterestTimedOutNo() >= 
+				                       pnlsr.getConfParameter().getInterestRetryNumber())
+			{
+					nbrCount++;
+			}
+		} 
+	}
+
+	if( nbrCount == adjList.size())
+	{
+		return true;
+	}
+
+	return false;
+}
+
+int 
+Adl::getNumOfActiveNeighbor()
+{
+	int actNbrCount=0;
+	for( std::list<Adjacent>::iterator it=adjList.begin(); 
+	                                                   it!= adjList.end() ; it++)
+	{
+		if ( ((*it).getStatus() == 1 ) )
+		{
+			actNbrCount++;
+		}
+	}
+
+	return actNbrCount;
+}
+
+// used for debugging purpose
+void
+Adl::printAdl(){
+	for( std::list<Adjacent>::iterator it=adjList.begin(); it!= adjList.end() ; it++){
+		cout<< (*it) <<endl;
+	}
+}
