diff --git a/ChangeLog b/ChangeLog
index e737d062..4a1ec76c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,58 @@
+2007-03-19  Tatsuhiro Tsujikawa  <tujikawa at valkyrie dot rednoah com>
+
+	To integrate Netrc into exsiting classes:
+	* src/Request.h
+	(_userDefinedAuthConfig): New variable.
+	(findNetrcAuthenticator): New function.
+	(segment): Removed.
+	(setUserDefinedAuthConfig): New function.
+	(resolveHttpAuthConfigItem): New function.
+	(resolveFtpAuthConfigItem): New function.
+	(resolveHttpProxyAuthConfigItem): New function.
+	* src/HttpRequest.h
+	(authConfig): Removed.
+	(proxyAuthConfig): Removed.
+	(setAuthConfig): Removed.
+	(setProxyAuthConfig): Removed.
+	* src/UrlRequest.h
+	(getHeadResult): Added a parameter: authConfigHandle
+	* src/common.h
+	(SingletonHolder.h): New include.
+	* src/main.cc
+	(Netrc.h): New include.
+	(main): Removed initial values of PREF_FTP_USER, PREF_FTP_PASSWD.
+	Added initial value of PREF_NETRC_PATH.
+	Added the initialization of netrc.
+	* src/AuthConfig.h: New class.
+	* src/prefs.h
+	(PREF_NETRC_PATH): New definition.
+	* src/HttpAuthConfig.h: Removed.
+	* src/Netrc.cc
+	(getRequiredNextToken): New function.
+	(skipMacdef): New function.
+	(parse): Rewritten.
+	* src/Netrc.h
+	(getRequiredNextToken): New function.
+	(skipMacdef): New function.
+	* src/Util.h, src/Util.cc
+	(getHomeDir): New function.
+	* src/TrackerWatcherComand.cc
+	(createRequestCommand): Use AuthConfig.
+	* src/FtpConnection.cc
+	(sendUser): Use Request::resolveFtpAuthConfigItem().
+	(sendPass): Use Request::resolveFtpAuthConfigItem().
+	* src/Request.cc
+	(findNetrcAuthenticator): New function.
+	(resolveHttpAuthConfigItem): New function.
+	(resolveFtpAuthConfigItem): New function.
+	(resolveHttpProxyAuthConfigItem): New function.
+	* src/UrlRequestInfo.cc: Use AuthConfig.
+	* src/HttpRequest.cc
+	(createRequest): Use authConfig.
+	(getProxyAuthString): Use authConfig.
+	(configure): Removed PREF_HTTP_USER, PREF_HTTP_PASSWD,
+	PREF_HTTP_PROXY_USER, PREF_HTTP_PROXY_PASSWD.
+	
 2007-03-16  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
 
 	To reduce overhead to find commands whose socket is either
@@ -14,8 +69,6 @@
 	(waitData): Call Command::setStatusActive() when command's socket is
 	readable or writable.
 
-	
-
 2007-03-15  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
 
 	To handle Segment as SegmentHandle:
diff --git a/TODO b/TODO
index 2db8af0a..2be6e641 100644
--- a/TODO
+++ b/TODO
@@ -25,3 +25,5 @@
 * Add an ability of seeding
 * Continue file allocation with existing file
 * Rewrite HttpConnection::receiveResponse() using {i,o}stringstream
+* -c command line option to continue the download of existing file assuming
+that it was downloaded from the beginning.
\ No newline at end of file
diff --git a/src/AuthConfig.h b/src/AuthConfig.h
new file mode 100644
index 00000000..580c4853
--- /dev/null
+++ b/src/AuthConfig.h
@@ -0,0 +1,106 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL.  If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so.  If you
+ * do not wish to do so, delete this exception statement from your
+ * version.  If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_AUTH_CONFIG_H_
+#define _D_AUTH_CONFIG_H_
+
+#include "common.h"
+#include "AuthConfigItem.h"
+#include "prefs.h"
+#include "Option.h"
+
+class AuthConfig {
+private:
+  AuthConfigItemHandle httpAuthConfigItem;
+  AuthConfigItemHandle ftpAuthConfigItem;
+  AuthConfigItemHandle httpProxyAuthConfigItem;
+
+  AuthConfigItemHandle createAuthConfigItem(const string& user, const string& password)
+  {
+    if(user.length() > 0) {
+      return new AuthConfigItem(user, password);
+    } else {
+      return 0;
+    }
+  }
+public:
+
+  AuthConfig():httpAuthConfigItem(0),
+	       ftpAuthConfigItem(0),
+	       httpProxyAuthConfigItem(0) {}
+
+  AuthConfigItemHandle getHttpAuthConfigItem() const
+  {
+    return httpAuthConfigItem;
+  }
+  
+  void setHttpAuthConfigItem(const string& user, const string& password)
+  {
+    httpAuthConfigItem = createAuthConfigItem(user, password);
+  }
+
+  AuthConfigItemHandle getFtpAuthConfigItem() const
+  {
+    return ftpAuthConfigItem;
+  }
+
+  void setFtpAuthConfigItem(const string& user, const string& password)
+  {
+    ftpAuthConfigItem = createAuthConfigItem(user, password);
+  }
+
+  AuthConfigItemHandle getHttpProxyAuthConfigItem() const
+  {
+    return httpProxyAuthConfigItem;
+  }
+
+  void setHttpProxyAuthConfigItem(const string& user, const string& password)
+  {
+    httpProxyAuthConfigItem = createAuthConfigItem(user, password);
+  }
+
+  void configure(const Option* op)
+  {
+    setHttpAuthConfigItem(op->get(PREF_HTTP_USER),
+			  op->get(PREF_HTTP_PASSWD));
+    setFtpAuthConfigItem(op->get(PREF_FTP_USER),
+			 op->get(PREF_FTP_PASSWD));
+    setHttpProxyAuthConfigItem(op->get(PREF_HTTP_PROXY_USER),
+			       op->get(PREF_HTTP_PROXY_PASSWD));
+  }
+};
+
+typedef SharedHandle<AuthConfig> AuthConfigHandle;
+
+#endif // _D_AUTH_CONFIG_H_
diff --git a/src/AuthConfigItem.h b/src/AuthConfigItem.h
new file mode 100644
index 00000000..68904251
--- /dev/null
+++ b/src/AuthConfigItem.h
@@ -0,0 +1,68 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL.  If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so.  If you
+ * do not wish to do so, delete this exception statement from your
+ * version.  If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_AUTH_CONFIG_ITEM_H_
+#define _D_AUTH_CONFIG_ITEM_H_
+
+#include "common.h"
+
+class AuthConfigItem {
+private:
+  string _authScheme;
+  string _user;
+  string _password;
+public:
+
+  AuthConfigItem(const string& user, const string& password):
+    _user(user), _password(password) {}
+
+  string getAuthText() const
+  {
+    return _user+":"+_password;
+  }
+
+  const string& getUser() const
+  {
+    return _user;
+  }
+
+  const string& getPassword() const
+  {
+    return _password;
+  }
+};
+
+typedef SharedHandle<AuthConfigItem> AuthConfigItemHandle;
+
+#endif // _D_AUTH_CONFIG_ITEM_H_
diff --git a/src/FtpConnection.cc b/src/FtpConnection.cc
index 48bd416a..edb58109 100644
--- a/src/FtpConnection.cc
+++ b/src/FtpConnection.cc
@@ -49,13 +49,13 @@ FtpConnection::FtpConnection(int cuid, const SocketHandle& socket,
 FtpConnection::~FtpConnection() {}
 
 void FtpConnection::sendUser() const {
-  string request = "USER "+option->get(PREF_FTP_USER)+"\r\n";
+  string request = "USER "+req->resolveFtpAuthConfigItem()->getUser()+"\r\n";
   logger->info(MSG_SENDING_REQUEST, cuid, request.c_str());
   socket->writeData(request);
 }
 
 void FtpConnection::sendPass() const {
-  string request = "PASS "+option->get(PREF_FTP_PASSWD)+"\r\n";
+  string request = "PASS "+req->resolveFtpAuthConfigItem()->getPassword()+"\r\n";
   logger->info(MSG_SENDING_REQUEST, cuid, "PASS ********");
   socket->writeData(request);
 }
diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc
index b746f612..19cfdbe1 100644
--- a/src/HttpRequest.cc
+++ b/src/HttpRequest.cc
@@ -107,7 +107,7 @@ string HttpRequest::createRequest() const
   }
   if(authEnabled) {
     requestLine += "Authorization: Basic "+
-	Base64::encode(authConfig->getAuthText())+"\r\n";
+	Base64::encode(request->resolveHttpAuthConfigItem()->getAuthText())+"\r\n";
   }
   if(getPreviousURI().size()) {
     requestLine += "Referer: "+getPreviousURI()+"\r\n";
@@ -145,7 +145,7 @@ string HttpRequest::createProxyRequest() const
 
 string HttpRequest::getProxyAuthString() const {
   return "Proxy-Authorization: Basic "+
-    Base64::encode(proxyAuthConfig->getAuthText())+"\r\n";
+    Base64::encode(request->resolveHttpProxyAuthConfigItem()->getAuthText())+"\r\n";
 }
 
 void HttpRequest::configure(const Option* option)
@@ -155,8 +155,4 @@ void HttpRequest::configure(const Option* option)
     option->get(PREF_HTTP_PROXY_ENABLED) == V_TRUE &&
     option->get(PREF_HTTP_PROXY_METHOD) == V_GET;
   proxyAuthEnabled = option->get(PREF_HTTP_PROXY_AUTH_ENABLED) == V_TRUE;
-  authConfig = new HttpAuthConfig(option->get(PREF_HTTP_USER),
-				  option->get(PREF_HTTP_PASSWD));
-  proxyAuthConfig = new HttpAuthConfig(option->get(PREF_HTTP_PROXY_USER),
-				       option->get(PREF_HTTP_PROXY_PASSWD));
 }
diff --git a/src/HttpRequest.h b/src/HttpRequest.h
index d6f4ca4f..8cfe45d9 100644
--- a/src/HttpRequest.h
+++ b/src/HttpRequest.h
@@ -39,7 +39,6 @@
 #include "Segment.h"
 #include "Range.h"
 #include "Request.h"
-#include "HttpAuthConfig.h"
 #include "Option.h"
 #include <netinet/in.h>
 
@@ -54,14 +53,10 @@ private:
 
   bool authEnabled;
 
-  HttpAuthConfigHandle authConfig;
-
   bool proxyEnabled;
 
   bool proxyAuthEnabled;
 
-  HttpAuthConfigHandle proxyAuthConfig;
-
   string userAgent;
 
   string getHostText(const string& host, in_port_t port) const;
@@ -73,10 +68,8 @@ public:
 		segment(0),
 		entityLength(0),
 		authEnabled(false),
-		authConfig(0),
 		proxyEnabled(false),
 		proxyAuthEnabled(false),
-		proxyAuthConfig(0),
 		userAgent(USER_AGENT)
   {}
 
@@ -221,16 +214,6 @@ public:
     this->authEnabled = authEnabled;
   }
 
-  void setAuthConfig(const HttpAuthConfigHandle& authConfig)
-  {
-    this->authConfig = authConfig;
-  }
-
-  void setProxyAuthConfig(const HttpAuthConfigHandle& proxyAuthConfig)
-  {
-    this->proxyAuthConfig = proxyAuthConfig;
-  }
-
   void setUserAgent(const string& userAgent)
   {
     this->userAgent = userAgent;
diff --git a/src/Netrc.cc b/src/Netrc.cc
index a30e8485..4538f526 100644
--- a/src/Netrc.cc
+++ b/src/Netrc.cc
@@ -37,6 +37,27 @@
 #include "RecoverableException.h"
 #include <fstream>
 
+string Netrc::getRequiredNextToken(ifstream& f) const
+{
+  string token;
+  if(f >> token) {
+    return token;
+  } else {
+    throw new RecoverableException("Netrc:parse error. EOF reached where a token expected.");
+  }
+}
+
+void Netrc::skipMacdef(ifstream& f) const
+{
+  string line;
+  getline(f, line);
+  while(getline(f, line)) {
+    if(line == "\r" || line == "") {
+      break;
+    }
+  }
+}
+
 void Netrc::parse(const string& path)
 {
   authenticators.clear();
@@ -46,32 +67,29 @@ void Netrc::parse(const string& path)
     throw new RecoverableException("File not found: %s", path.c_str());
   }
 
-  int32_t lineNum = 0;
-  string line;
   AuthenticatorHandle authenticator = 0;
-  while(getline(f, line)) {
-    ++lineNum;
-    if(Util::trim(line).empty()) {
-      continue;
-    }
-    pair<string, string> nameValuePair = Util::split(line, "\r\n\t ");
-    if(nameValuePair.first == "machine") {
+  string token;
+  while(f >> token) {
+    if(token == "machine") {
       storeAuthenticator(authenticator);
       authenticator = new Authenticator();
-      authenticator->setMachine(nameValuePair.second);
-    } else if(nameValuePair.first == "default") {
+      authenticator->setMachine(getRequiredNextToken(f));
+    } else if(token == "default") {
       storeAuthenticator(authenticator);
       authenticator = new DefaultAuthenticator();
     } else {
       if(authenticator.isNull()) {
-	throw new RecoverableException("Malformed netrc file: line %d", lineNum);
+	throw new RecoverableException("Netrc:parse error. %s encounterd where 'machine' or 'default' expected.");
       }
-      if(nameValuePair.first == "login") {
-	authenticator->setLogin(nameValuePair.second);
-      } else if(nameValuePair.first == "password") {
-	authenticator->setPassword(nameValuePair.second);
-      } else if(nameValuePair.first == "account") {
-	authenticator->setAccount(nameValuePair.second);
+      if(token == "login") {
+	authenticator->setLogin(getRequiredNextToken(f));
+      } else if(token == "password") {
+	authenticator->setPassword(getRequiredNextToken(f));
+      } else if(token == "account") {
+	authenticator->setAccount(getRequiredNextToken(f));
+      } else if(token == "macdef") {
+	getRequiredNextToken(f);
+	skipMacdef(f);
       }
     }
   }
diff --git a/src/Netrc.h b/src/Netrc.h
index b36599eb..07f7c738 100644
--- a/src/Netrc.h
+++ b/src/Netrc.h
@@ -127,6 +127,10 @@ private:
   Authenticators authenticators;
 
   void storeAuthenticator(const AuthenticatorHandle& authenticator);
+
+  string getRequiredNextToken(ifstream& f) const;
+  
+  void skipMacdef(ifstream& f) const;
 public:
   Netrc() {}
 
diff --git a/src/Request.cc b/src/Request.cc
index 62248826..8ff53a88 100644
--- a/src/Request.cc
+++ b/src/Request.cc
@@ -35,12 +35,16 @@
 #include "Request.h"
 #include "Util.h"
 #include "FeatureConfig.h"
+#include "Netrc.h"
 
 const string Request::METHOD_GET = "get";
 
 const string Request::METHOD_HEAD = "head";
 
-Request::Request():port(0), tryCount(0), keepAlive(true), method(METHOD_GET), isTorrent(false) {
+Request::Request():port(0), tryCount(0), keepAlive(true), method(METHOD_GET),
+		   _userDefinedAuthConfig(0),
+		   isTorrent(false)
+{
   cookieBox = new CookieBox();
 }
 
@@ -55,7 +59,6 @@ bool Request::setUrl(const string& url) {
 
 bool Request::resetUrl() {
   previousUrl = referer;
-  segment = Segment();
   return setUrl(url);
 }
 
@@ -130,3 +133,52 @@ bool Request::parseUrl(const string& url) {
   file += query;
   return true;
 }
+
+AuthConfigItemHandle Request::findNetrcAuthenticator() const
+{
+  if(!NetrcSingletonHolder::instance().isNull()) {
+    AuthenticatorHandle auth = NetrcSingletonHolder::instance()->findAuthenticator(getHost());
+    if(auth.isNull()) {
+      return 0;
+    } else {
+      return new AuthConfigItem(auth->getLogin(), auth->getPassword());
+    }
+  } else {
+    return 0;
+  }
+}
+
+AuthConfigItemHandle Request::resolveHttpAuthConfigItem() const
+{
+  if(!_userDefinedAuthConfig.isNull() &&
+     !_userDefinedAuthConfig->getHttpAuthConfigItem().isNull()) {
+    return _userDefinedAuthConfig->getHttpAuthConfigItem();
+  } else {
+    return findNetrcAuthenticator();
+  }
+}
+
+AuthConfigItemHandle Request::resolveFtpAuthConfigItem() const
+{
+  if(!_userDefinedAuthConfig.isNull() &&
+     !_userDefinedAuthConfig->getFtpAuthConfigItem().isNull()) {
+    return _userDefinedAuthConfig->getFtpAuthConfigItem();
+  } else {
+    AuthConfigItemHandle authConfig = findNetrcAuthenticator();
+    if(authConfig.isNull()) {
+      return new AuthConfigItem("anonymous", "ARIA2USER@");
+    } else {
+      return authConfig;
+    }
+  }
+}
+
+AuthConfigItemHandle Request::resolveHttpProxyAuthConfigItem() const
+{
+  if(!_userDefinedAuthConfig.isNull() &&
+     !_userDefinedAuthConfig->getHttpProxyAuthConfigItem().isNull()) {
+    return _userDefinedAuthConfig->getHttpProxyAuthConfigItem();
+  } else {
+    return findNetrcAuthenticator();
+  }
+}
diff --git a/src/Request.h b/src/Request.h
index 04f8aad7..f7b9c9ec 100644
--- a/src/Request.h
+++ b/src/Request.h
@@ -34,14 +34,9 @@
 /* copyright --> */
 #ifndef _D_REQUEST_H_
 #define _D_REQUEST_H_
-#include <string>
-#include <map>
-#include "CookieBox.h"
-#include "Segment.h"
 #include "common.h"
-#include "SharedHandle.h"
-
-using namespace std;
+#include "CookieBox.h"
+#include "AuthConfig.h"
 
 #define SAFE_CHARS "abcdefghijklmnopqrstuvwxyz"\
 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"\
@@ -75,9 +70,14 @@ private:
   int trackerEvent;
   bool keepAlive;
   string method;
+
+  AuthConfigHandle _userDefinedAuthConfig;
+  
   bool parseUrl(const string& url);
+
+  AuthConfigItemHandle findNetrcAuthenticator() const;
+
 public:
-  Segment segment;
   CookieBox* cookieBox;
   bool isTorrent;
 public:
@@ -116,6 +116,17 @@ public:
     this->method = method;
   }
 
+  void setUserDefinedAuthConfig(const AuthConfigHandle& authConfig)
+  {
+    _userDefinedAuthConfig = authConfig;
+  }
+
+  AuthConfigItemHandle resolveHttpAuthConfigItem() const;
+
+  AuthConfigItemHandle resolveFtpAuthConfigItem() const;
+
+  AuthConfigItemHandle resolveHttpProxyAuthConfigItem() const;
+
   const string& getMethod() const {
     return method;
   }
diff --git a/src/HttpAuthConfig.h b/src/SingletonHolder.h
similarity index 78%
rename from src/HttpAuthConfig.h
rename to src/SingletonHolder.h
index 4367a78e..d6d2eebf 100644
--- a/src/HttpAuthConfig.h
+++ b/src/SingletonHolder.h
@@ -32,27 +32,30 @@
  * files in the program, then also delete it here.
  */
 /* copyright --> */
-#ifndef _D_HTTP_AUTH_CONFIG_H_
-#define _D_HTTP_AUTH_CONFIG_H_
+#ifndef _D_SINGLETON_HOLDER_H_
+#define _D_SINGLETON_HOLDER_H_
 
-#include "common.h"
-
-class HttpAuthConfig {
+template<typename T>
+class SingletonHolder {
 private:
-  string authScheme;
-  string authUser;
-  string authPassword;
+  static T _instance;
+
+  SingletonHolder() {}
 public:
+  ~SingletonHolder() {}
 
-  HttpAuthConfig(const string& authUser, const string& authPassword):
-    authUser(authUser), authPassword(authPassword) {}
-
-  string getAuthText() const
+  static T& instance()
   {
-    return authUser+":"+authPassword;
+    return _instance;
+  }
+
+  static void instance(T& instance)
+  {
+    _instance = instance;
   }
 };
 
-typedef SharedHandle<HttpAuthConfig> HttpAuthConfigHandle;
+template<typename T>
+T SingletonHolder<T>::_instance = 0;
 
-#endif // _D_HTTP_AUTH_CONFIG_H_
+#endif // _D_SINGLETON_HOLDER_H_
diff --git a/src/TrackerWatcherCommand.cc b/src/TrackerWatcherCommand.cc
index 8d98e682..2afb6dc2 100644
--- a/src/TrackerWatcherCommand.cc
+++ b/src/TrackerWatcherCommand.cc
@@ -81,8 +81,11 @@ Command* TrackerWatcherCommand::createCommand() {
 }
 
 Command* TrackerWatcherCommand::createRequestCommand(const string& url) {
+  AuthConfigHandle authConfig = new AuthConfig();
+  authConfig->configure(e->option);
   RequestHandle req;
   req->setUrl(url);
+  req->setUserDefinedAuthConfig(authConfig);
   req->isTorrent = true;
   Command* command =
     InitiateConnectionCommandFactory::createInitiateConnectionCommand(btRuntime->getNewCuid(), req, e);
diff --git a/src/UrlRequestInfo.cc b/src/UrlRequestInfo.cc
index d33924fb..38778c36 100644
--- a/src/UrlRequestInfo.cc
+++ b/src/UrlRequestInfo.cc
@@ -88,15 +88,18 @@ private:
   Requests* requestsPtr;
   string referer;
   int split;
+  AuthConfigHandle _userDefinedAuthConfig;
   string method;
 public:
   CreateRequest(Requests* requestsPtr,
 		const string& referer,
 		int split,
+		const AuthConfigHandle& userDefinedAuthConfig,
 		const string& method = Request::METHOD_GET)
     :requestsPtr(requestsPtr),
      referer(referer),
      split(split),
+     _userDefinedAuthConfig(userDefinedAuthConfig),
      method(method) {}
 
   void operator()(const string& url) {
@@ -104,6 +107,7 @@ public:
       RequestHandle req;
       req->setReferer(referer);
       req->setMethod(method);
+      req->setUserDefinedAuthConfig(_userDefinedAuthConfig);
       if(req->setUrl(url)) {
 	requestsPtr->push_back(req);
       } else {
@@ -120,12 +124,13 @@ void UrlRequestInfo::printUrls(const Strings& urls) const {
   }
 }
 
-HeadResultHandle UrlRequestInfo::getHeadResult() {
+HeadResultHandle UrlRequestInfo::getHeadResult(const AuthConfigHandle& authConfig) {
   Requests requests;
   for_each(urls.begin(), urls.end(),
 	   CreateRequest(&requests,
 			 op->get(PREF_REFERER),
 			 1,
+			 authConfig,
 			 Request::METHOD_HEAD));
   if(requests.size() == 0) {
     return 0;
@@ -153,12 +158,17 @@ RequestInfos UrlRequestInfo::execute() {
   Requests requests;
   Requests reserved;
   printUrls(urls);
-  HeadResultHandle hr = getHeadResult();
 
+  AuthConfigHandle authConfig = new AuthConfig();
+  authConfig->configure(op);
+
+  HeadResultHandle hr = getHeadResult(authConfig);
+  
   for_each(urls.begin(), urls.end(),
 	   CreateRequest(&requests,
 			 op->get(PREF_REFERER),
-			 op->getAsInt(PREF_SPLIT)));
+			 op->getAsInt(PREF_SPLIT),
+			 authConfig));
   
   logger->info("Head result: filename=%s, total length=%s",
 	       hr->filename.c_str(), Util::ullitos(hr->totalLength, true).c_str());
diff --git a/src/UrlRequestInfo.h b/src/UrlRequestInfo.h
index 94e1680b..e349f19b 100644
--- a/src/UrlRequestInfo.h
+++ b/src/UrlRequestInfo.h
@@ -64,7 +64,7 @@ private:
 			 Requests& reserved,
 			 int maxConnections) const;
   void printUrls(const Strings& urls) const;
-  HeadResultHandle getHeadResult();
+  HeadResultHandle getHeadResult(const AuthConfigHandle& authConfig);
 public:
   UrlRequestInfo(const Strings& urls, int maxConnections, Option* op):
     RequestInfo(op),
diff --git a/src/Util.cc b/src/Util.cc
index 89d241fd..2c096f3e 100644
--- a/src/Util.cc
+++ b/src/Util.cc
@@ -664,3 +664,12 @@ void Util::indexRange(int32_t& startIndex, int32_t& endIndex,
   endIndex = _endIndex;
 }
 
+string Util::getHomeDir()
+{
+  const char* p = getenv("HOME");
+  if(p) {
+    return p;
+  } else {
+    return "";
+  }
+}
diff --git a/src/Util.h b/src/Util.h
index fd1f1cd1..6127b41e 100644
--- a/src/Util.h
+++ b/src/Util.h
@@ -144,6 +144,8 @@ public:
   static void indexRange(int32_t& startIndex, int32_t& endIndex,
 			 int64_t offset,
 			 int32_t srcLength, int32_t destLength);
+
+  static string getHomeDir();
 };
 
 #endif // _D_UTIL_H_
diff --git a/src/common.h b/src/common.h
index 91049cb5..fd0e9c70 100644
--- a/src/common.h
+++ b/src/common.h
@@ -70,6 +70,7 @@ public:
 };
 
 #include "SharedHandle.h"
+#include "SingletonHolder.h"
 
 typedef deque<string> Strings;
 typedef deque<int32_t> Integers;
diff --git a/src/main.cc b/src/main.cc
index b6533ed5..97d4fda5 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -48,6 +48,7 @@
 #include "BitfieldManFactory.h"
 #include "SimpleRandomizer.h"
 #include "ConsoleFileAllocationMonitor.h"
+#include "Netrc.h"
 #include <deque>
 #include <algorithm>
 #include <time.h>
@@ -342,8 +343,6 @@ int main(int argc, char* argv[]) {
   op->put(PREF_MAX_TRIES, "5");
   op->put(PREF_HTTP_AUTH_SCHEME, V_BASIC);
   op->put(PREF_HTTP_PROXY_METHOD, V_TUNNEL);
-  op->put(PREF_FTP_USER, "anonymous");
-  op->put(PREF_FTP_PASSWD, "ARIA2USER@");
   op->put(PREF_FTP_TYPE, V_BINARY);
   op->put(PREF_FTP_VIA_HTTP_PROXY, V_TUNNEL);
   op->put(PREF_AUTO_SAVE_INTERVAL, "60");
@@ -357,6 +356,7 @@ int main(int argc, char* argv[]) {
   op->put(PREF_ALLOW_OVERWRITE, V_FALSE);
   op->put(PREF_REALTIME_CHUNK_CHECKSUM, V_TRUE);
   op->put(PREF_CHECK_INTEGRITY, V_FALSE);
+  op->put(PREF_NETRC_PATH, Util::getHomeDir()+"/.netrc");
   while(1) {
     int optIndex = 0;
     int lopt;
@@ -773,6 +773,10 @@ int main(int argc, char* argv[]) {
     logger->info("%s %s", PACKAGE, PACKAGE_VERSION);
     logger->info("Logging started.");
 
+    NetrcHandle netrc = new Netrc();
+    netrc->parse(op->get(PREF_NETRC_PATH));
+    NetrcSingletonHolder::instance(netrc);
+
     Util::setGlobalSignalHandler(SIGPIPE, SIG_IGN, 0);
 
     RequestInfo* firstReqInfo = 0;
diff --git a/src/prefs.h b/src/prefs.h
index 95e8c312..4846f80b 100644
--- a/src/prefs.h
+++ b/src/prefs.h
@@ -90,6 +90,8 @@
 #define PREF_REALTIME_CHUNK_CHECKSUM "realtime_chunk_checksum"
 // value: true | false
 #define PREF_CHECK_INTEGRITY "check_integrity"
+// value: string that your file system recognizes as a file name.
+#define PREF_NETRC_PATH "netrc_path"
 
 /**
  * FTP related preferences
diff --git a/test/AuthConfigTest.cc b/test/AuthConfigTest.cc
new file mode 100644
index 00000000..c80ba7fe
--- /dev/null
+++ b/test/AuthConfigTest.cc
@@ -0,0 +1,43 @@
+#include "AuthConfig.h"
+#include "Option.h"
+#include "prefs.h"
+#include <cppunit/extensions/HelperMacros.h>
+
+class AuthConfigTest:public CppUnit::TestFixture {
+
+  CPPUNIT_TEST_SUITE(AuthConfigTest);
+  CPPUNIT_TEST(testGet);
+  CPPUNIT_TEST_SUITE_END();
+  
+public:
+  void testGet();
+};
+
+
+CPPUNIT_TEST_SUITE_REGISTRATION( AuthConfigTest );
+
+void AuthConfigTest::testGet()
+{
+  Option option;
+  option.put(PREF_HTTP_USER, "httpUser");
+  option.put(PREF_HTTP_PASSWD, "httpPassword");
+  option.put(PREF_FTP_USER, "ftpUser");
+  option.put(PREF_FTP_PASSWD, "ftpPassword");
+  option.put(PREF_HTTP_PROXY_USER, "httpProxyUser");
+  option.put(PREF_HTTP_PROXY_PASSWD, "httpProxyPassword");
+
+  AuthConfig authConfig;
+  authConfig.configure(&option);
+
+  AuthConfigItemHandle httpAuth = authConfig.getHttpAuthConfigItem();
+  CPPUNIT_ASSERT_EQUAL(string("httpUser"), httpAuth->getUser());
+  CPPUNIT_ASSERT_EQUAL(string("httpPassword"), httpAuth->getPassword());
+
+  AuthConfigItemHandle ftpAuth = authConfig.getFtpAuthConfigItem();
+  CPPUNIT_ASSERT_EQUAL(string("ftpUser"), ftpAuth->getUser());
+  CPPUNIT_ASSERT_EQUAL(string("ftpPassword"), ftpAuth->getPassword());
+
+  AuthConfigItemHandle httpProxyAuth = authConfig.getHttpProxyAuthConfigItem();
+  CPPUNIT_ASSERT_EQUAL(string("httpProxyUser"), httpProxyAuth->getUser());
+  CPPUNIT_ASSERT_EQUAL(string("httpProxyPassword"), httpProxyAuth->getPassword());
+}
diff --git a/test/HttpRequestTest.cc b/test/HttpRequestTest.cc
index a777a0ea..671d1628 100644
--- a/test/HttpRequestTest.cc
+++ b/test/HttpRequestTest.cc
@@ -81,6 +81,9 @@ void HttpRequestTest::testCreateRequest()
 {
   RequestHandle request = new Request();
   request->setUrl("http://localhost:8080/archives/aria2-1.0.0.tar.bz2");
+  AuthConfigHandle authConfig = new AuthConfig();
+  request->setUserDefinedAuthConfig(authConfig);
+
   SegmentHandle segment = new Segment();
 
   HttpRequest httpRequest;
@@ -168,6 +171,7 @@ void HttpRequestTest::testCreateRequest()
   option->put(PREF_HTTP_PROXY_USER, "aria2proxyuser");
   option->put(PREF_HTTP_PROXY_PASSWD, "aria2proxypasswd");
 
+  authConfig->configure(option.get());
   httpRequest.configure(option.get());
 
   expectedText = "GET /archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
@@ -278,6 +282,8 @@ void HttpRequestTest::testCreateRequest_ftp()
 {
   RequestHandle request = new Request();
   request->setUrl("ftp://localhost:8080/archives/aria2-1.0.0.tar.bz2");
+  AuthConfigHandle authConfig = new AuthConfig();
+  request->setUserDefinedAuthConfig(authConfig);
   SegmentHandle segment = new Segment();
 
   HttpRequest httpRequest;
@@ -296,6 +302,7 @@ void HttpRequestTest::testCreateRequest_ftp()
   option->put(PREF_HTTP_PROXY_PASSWD, "aria2proxypasswd");
 
   httpRequest.configure(option.get());
+  authConfig->configure(option.get());
 
   string expectedText = "GET ftp://localhost:8080/archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
     "User-Agent: aria2\r\n"
diff --git a/test/Makefile.am b/test/Makefile.am
index 9317de6e..d13dcf15 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,10 +1,12 @@
 TESTS = aria2c
 check_PROGRAMS = $(TESTS)
 aria2c_SOURCES = AllTest.cc\
-	HttpHeaderTest.cc\
-	HttpRequestTest.cc\
-	HttpResponseTest.cc\
 	NetrcTest.cc\
+	HttpRequestTest.cc\
+	AuthConfigTest.cc\
+	SingletonHolderTest.cc\
+	HttpHeaderTest.cc\
+	HttpResponseTest.cc\
 	BitfieldManTest.cc\
 	SharedHandleTest.cc\
 	RequestTest.cc\
diff --git a/test/Makefile.in b/test/Makefile.in
index 1e38ccca..e86bd085 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -57,9 +57,10 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
 am__EXEEXT_1 = aria2c$(EXEEXT)
-am_aria2c_OBJECTS = AllTest.$(OBJEXT) HttpHeaderTest.$(OBJEXT) \
-	HttpRequestTest.$(OBJEXT) HttpResponseTest.$(OBJEXT) \
-	NetrcTest.$(OBJEXT) BitfieldManTest.$(OBJEXT) \
+am_aria2c_OBJECTS = AllTest.$(OBJEXT) NetrcTest.$(OBJEXT) \
+	HttpRequestTest.$(OBJEXT) AuthConfigTest.$(OBJEXT) \
+	SingletonHolderTest.$(OBJEXT) HttpHeaderTest.$(OBJEXT) \
+	HttpResponseTest.$(OBJEXT) BitfieldManTest.$(OBJEXT) \
 	SharedHandleTest.$(OBJEXT) RequestTest.$(OBJEXT) \
 	ChunkedEncodingTest.$(OBJEXT) FileTest.$(OBJEXT) \
 	OptionTest.$(OBJEXT) Base64Test.$(OBJEXT) UtilTest.$(OBJEXT) \
@@ -258,10 +259,12 @@ sysconfdir = @sysconfdir@
 target_alias = @target_alias@
 TESTS = aria2c
 aria2c_SOURCES = AllTest.cc\
-	HttpHeaderTest.cc\
-	HttpRequestTest.cc\
-	HttpResponseTest.cc\
 	NetrcTest.cc\
+	HttpRequestTest.cc\
+	AuthConfigTest.cc\
+	SingletonHolderTest.cc\
+	HttpHeaderTest.cc\
+	HttpResponseTest.cc\
 	BitfieldManTest.cc\
 	SharedHandleTest.cc\
 	RequestTest.cc\
@@ -386,6 +389,7 @@ distclean-compile:
 
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AllTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AnnounceListTest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AuthConfigTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Base64Test.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BitfieldManTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtAllowedFastMessageTest.Po@am__quote@
@@ -439,6 +443,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ShaVisitorTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ShareRatioSeedCriteriaTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SharedHandleTest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SingletonHolderTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SpeedCalcTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeSeedCriteriaTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TrackerWatcherCommandTest.Po@am__quote@
diff --git a/test/NetrcTest.cc b/test/NetrcTest.cc
index a02b7117..caa6dff7 100644
--- a/test/NetrcTest.cc
+++ b/test/NetrcTest.cc
@@ -7,10 +7,11 @@ using namespace std;
 class NetrcTest : public CppUnit::TestFixture {
 
   CPPUNIT_TEST_SUITE(NetrcTest);
-  CPPUNIT_TEST(testFindAuthenticatable);
+  CPPUNIT_TEST(testFindAuthenticator);
   CPPUNIT_TEST(testParse);
   CPPUNIT_TEST(testParse_fileNotFound);
   CPPUNIT_TEST(testParse_emptyfile);
+  CPPUNIT_TEST(testParse_malformedNetrc);
   CPPUNIT_TEST_SUITE_END();
 private:
 
@@ -18,29 +19,30 @@ public:
   void setUp() {
   }
 
-  void testFindAuthenticatable();
+  void testFindAuthenticator();
   void testParse();
   void testParse_fileNotFound();
   void testParse_emptyfile();
+  void testParse_malformedNetrc();
 };
 
 
 CPPUNIT_TEST_SUITE_REGISTRATION( NetrcTest );
 
-void NetrcTest::testFindAuthenticatable()
+void NetrcTest::testFindAuthenticator()
 {
   Netrc netrc;
-  netrc.addAuthenticatable(new Authenticator("host1", "tujikawa", "tujikawapasswd", "tujikawaaccount"));
-  netrc.addAuthenticatable(new Authenticator("host2", "aria2", "aria2password", "aria2account"));
-  netrc.addAuthenticatable(new DefaultAuthenticator("default", "defaultpassword", "defaultaccount"));
+  netrc.addAuthenticator(new Authenticator("host1", "tujikawa", "tujikawapasswd", "tujikawaaccount"));
+  netrc.addAuthenticator(new Authenticator("host2", "aria2", "aria2password", "aria2account"));
+  netrc.addAuthenticator(new DefaultAuthenticator("default", "defaultpassword", "defaultaccount"));
 
-  AuthenticatorHandle aria2auth = netrc.findAuthenticatable("host2");
+  AuthenticatorHandle aria2auth = netrc.findAuthenticator("host2");
   CPPUNIT_ASSERT(!aria2auth.isNull());
   CPPUNIT_ASSERT_EQUAL(string("aria2"), aria2auth->getLogin());
   CPPUNIT_ASSERT_EQUAL(string("aria2password"), aria2auth->getPassword());
   CPPUNIT_ASSERT_EQUAL(string("aria2account"), aria2auth->getAccount());
 
-  AuthenticatorHandle defaultauth = netrc.findAuthenticatable("host3");
+  AuthenticatorHandle defaultauth = netrc.findAuthenticator("host3");
   CPPUNIT_ASSERT(!defaultauth.isNull());
   CPPUNIT_ASSERT_EQUAL(string("default"), defaultauth->getLogin());
   CPPUNIT_ASSERT_EQUAL(string("defaultpassword"), defaultauth->getPassword());
@@ -51,7 +53,7 @@ void NetrcTest::testParse()
 {
   Netrc netrc;
   netrc.parse("sample.netrc");
-  Authenticatables::const_iterator itr = netrc.getAuthenticatables().begin();
+  Authenticators::const_iterator itr = netrc.getAuthenticators().begin();
 
   AuthenticatorHandle tujikawaauth = *itr;
   CPPUNIT_ASSERT(!tujikawaauth.isNull());
@@ -91,5 +93,17 @@ void NetrcTest::testParse_emptyfile()
   Netrc netrc;
   netrc.parse("emptyfile");
 
-  CPPUNIT_ASSERT_EQUAL((size_t)0, netrc.getAuthenticatables().size());
+  CPPUNIT_ASSERT_EQUAL((size_t)0, netrc.getAuthenticators().size());
+}
+
+void NetrcTest::testParse_malformedNetrc()
+{
+  Netrc netrc;
+  try {
+    netrc.parse("malformed.netrc");
+    CPPUNIT_FAIL("exception must be threw.");
+  } catch(Exception* e) {
+    cerr << e->getMsg() << endl;
+    delete e;
+  }
 }
diff --git a/test/RequestTest.cc b/test/RequestTest.cc
index e5a1311b..d76f2c55 100644
--- a/test/RequestTest.cc
+++ b/test/RequestTest.cc
@@ -1,5 +1,5 @@
 #include "Request.h"
-
+#include "Netrc.h"
 #include <cppunit/extensions/HelperMacros.h>
 
 class RequestTest:public CppUnit::TestFixture {
@@ -25,6 +25,12 @@ class RequestTest:public CppUnit::TestFixture {
   CPPUNIT_TEST(testSafeChar);
   CPPUNIT_TEST(testInnerLink);
   CPPUNIT_TEST(testMetalink);
+  CPPUNIT_TEST(testResolveHttpAuthConfigItem);
+  CPPUNIT_TEST(testResolveHttpAuthConfigItem_noCandidate);
+  CPPUNIT_TEST(testResolveHttpProxyAuthConfigItem);
+  CPPUNIT_TEST(testResolveHttpProxyAuthConfigItem_noCandidate);
+  CPPUNIT_TEST(testResolveFtpAuthConfigItem);
+  CPPUNIT_TEST(testResolveFtpAuthConfigItem_noCandidate);
   CPPUNIT_TEST_SUITE_END();
   
 public:
@@ -48,6 +54,12 @@ public:
   void testSafeChar();
   void testInnerLink();
   void testMetalink();
+  void testResolveHttpAuthConfigItem();
+  void testResolveHttpAuthConfigItem_noCandidate();
+  void testResolveHttpProxyAuthConfigItem();
+  void testResolveHttpProxyAuthConfigItem_noCandidate();
+  void testResolveFtpAuthConfigItem();
+  void testResolveFtpAuthConfigItem_noCandidate();
 };
 
 
@@ -293,3 +305,118 @@ void RequestTest::testMetalink() {
   bool v2 = req.setUrl("http://aria.rednoah.com/download/aria.tar.bz2#!metalink3!");
   CPPUNIT_ASSERT(!v2);
 }
+
+void RequestTest::testResolveHttpAuthConfigItem()
+{
+  Request req;
+  req.setUrl("http://localhost/download/aria2-1.0.0.tar.bz2");
+  // with no authConfig
+  CPPUNIT_ASSERT(req.resolveHttpAuthConfigItem().isNull());
+
+  // with Netrc
+  NetrcHandle netrc = new Netrc();
+  netrc->addAuthenticator(new DefaultAuthenticator("default", "defaultpassword", "defaultaccount"));
+  NetrcSingletonHolder::instance(netrc);
+  CPPUNIT_ASSERT(!req.resolveHttpAuthConfigItem().isNull());
+  AuthConfigItemHandle authConfig1 = req.resolveHttpAuthConfigItem();
+  CPPUNIT_ASSERT_EQUAL(string("default"), authConfig1->getUser());
+  CPPUNIT_ASSERT_EQUAL(string("defaultpassword"), authConfig1->getPassword());
+
+  // with Netrc + user defined
+  AuthConfigHandle authConfig = new AuthConfig();
+  authConfig->setHttpAuthConfigItem("userDefinedUser", "userDefinedPassword");
+  req.setUserDefinedAuthConfig(authConfig);
+  CPPUNIT_ASSERT(!req.resolveHttpAuthConfigItem().isNull());
+  AuthConfigItemHandle authConfig2 = req.resolveHttpAuthConfigItem();
+  CPPUNIT_ASSERT_EQUAL(string("userDefinedUser"), authConfig2->getUser());
+  CPPUNIT_ASSERT_EQUAL(string("userDefinedPassword"), authConfig2->getPassword());
+}
+
+void RequestTest::testResolveHttpAuthConfigItem_noCandidate()
+{
+  Request req;
+  req.setUrl("http://localhost/download/aria2-1.0.0.tar.bz2");
+
+  NetrcHandle netrc = new Netrc();
+  netrc->addAuthenticator(new Authenticator("localhost2", "default", "defaultpassword", "defaultaccount"));
+  NetrcSingletonHolder::instance(netrc);
+  CPPUNIT_ASSERT(req.resolveHttpAuthConfigItem().isNull());
+}
+
+void RequestTest::testResolveHttpProxyAuthConfigItem()
+{
+  Request req;
+  req.setUrl("http://localhost/download/aria2-1.0.0.tar.bz2");
+  // with no authConfig
+  CPPUNIT_ASSERT(req.resolveHttpProxyAuthConfigItem().isNull());
+
+  // with Netrc
+  NetrcHandle netrc = new Netrc();
+  netrc->addAuthenticator(new DefaultAuthenticator("default", "defaultpassword", "defaultaccount"));
+  NetrcSingletonHolder::instance(netrc);
+  CPPUNIT_ASSERT(!req.resolveHttpProxyAuthConfigItem().isNull());
+  AuthConfigItemHandle authConfig1 = req.resolveHttpProxyAuthConfigItem();
+  CPPUNIT_ASSERT_EQUAL(string("default"), authConfig1->getUser());
+  CPPUNIT_ASSERT_EQUAL(string("defaultpassword"), authConfig1->getPassword());
+
+  // with Netrc + user defined
+  AuthConfigHandle authConfig = new AuthConfig();
+  authConfig->setHttpProxyAuthConfigItem("userDefinedUser", "userDefinedPassword");
+  req.setUserDefinedAuthConfig(authConfig);
+  CPPUNIT_ASSERT(!req.resolveHttpProxyAuthConfigItem().isNull());
+  AuthConfigItemHandle authConfig2 = req.resolveHttpProxyAuthConfigItem();
+  CPPUNIT_ASSERT_EQUAL(string("userDefinedUser"), authConfig2->getUser());
+  CPPUNIT_ASSERT_EQUAL(string("userDefinedPassword"), authConfig2->getPassword());
+}
+
+void RequestTest::testResolveHttpProxyAuthConfigItem_noCandidate()
+{
+  Request req;
+  req.setUrl("http://localhost/download/aria2-1.0.0.tar.bz2");
+
+  NetrcHandle netrc = new Netrc();
+  netrc->addAuthenticator(new Authenticator("localhost2", "default", "defaultpassword", "defaultaccount"));
+  NetrcSingletonHolder::instance(netrc);
+  CPPUNIT_ASSERT(req.resolveHttpProxyAuthConfigItem().isNull());
+}
+
+void RequestTest::testResolveFtpAuthConfigItem()
+{
+  Request req;
+  req.setUrl("http://localhost/download/aria2-1.0.0.tar.bz2");
+  // with no authConfig
+  CPPUNIT_ASSERT(!req.resolveFtpAuthConfigItem().isNull());
+  CPPUNIT_ASSERT_EQUAL(string("anonymous"), req.resolveFtpAuthConfigItem()->getUser());
+  CPPUNIT_ASSERT_EQUAL(string("ARIA2USER@"), req.resolveFtpAuthConfigItem()->getPassword());
+
+  // with Netrc
+  NetrcHandle netrc = new Netrc();
+  netrc->addAuthenticator(new DefaultAuthenticator("default", "defaultpassword", "defaultaccount"));
+  NetrcSingletonHolder::instance(netrc);
+  CPPUNIT_ASSERT(!req.resolveFtpAuthConfigItem().isNull());
+  AuthConfigItemHandle authConfig1 = req.resolveFtpAuthConfigItem();
+  CPPUNIT_ASSERT_EQUAL(string("default"), authConfig1->getUser());
+  CPPUNIT_ASSERT_EQUAL(string("defaultpassword"), authConfig1->getPassword());
+
+  // with Netrc + user defined
+  AuthConfigHandle authConfig = new AuthConfig();
+  authConfig->setFtpAuthConfigItem("userDefinedUser", "userDefinedPassword");
+  req.setUserDefinedAuthConfig(authConfig);
+  CPPUNIT_ASSERT(!req.resolveFtpAuthConfigItem().isNull());
+  AuthConfigItemHandle authConfig2 = req.resolveFtpAuthConfigItem();
+  CPPUNIT_ASSERT_EQUAL(string("userDefinedUser"), authConfig2->getUser());
+  CPPUNIT_ASSERT_EQUAL(string("userDefinedPassword"), authConfig2->getPassword());
+}
+
+void RequestTest::testResolveFtpAuthConfigItem_noCandidate()
+{
+  Request req;
+  req.setUrl("http://localhost/download/aria2-1.0.0.tar.bz2");
+
+  NetrcHandle netrc = new Netrc();
+  netrc->addAuthenticator(new Authenticator("localhost2", "default", "defaultpassword", "defaultaccount"));
+  NetrcSingletonHolder::instance(netrc);
+  CPPUNIT_ASSERT(!req.resolveFtpAuthConfigItem().isNull());
+  CPPUNIT_ASSERT_EQUAL(string("anonymous"), req.resolveFtpAuthConfigItem()->getUser());
+  CPPUNIT_ASSERT_EQUAL(string("ARIA2USER@"), req.resolveFtpAuthConfigItem()->getPassword());
+}
diff --git a/test/SingletonHolderTest.cc b/test/SingletonHolderTest.cc
new file mode 100644
index 00000000..71f99dfa
--- /dev/null
+++ b/test/SingletonHolderTest.cc
@@ -0,0 +1,57 @@
+#include "SingletonHolder.h"
+#include "SharedHandle.h"
+#include <cppunit/extensions/HelperMacros.h>
+
+using namespace std;
+
+class SingletonHolderTest : public CppUnit::TestFixture {
+
+  CPPUNIT_TEST_SUITE(SingletonHolderTest);
+  CPPUNIT_TEST(testInstance);
+  CPPUNIT_TEST_SUITE_END();
+private:
+
+public:
+  void setUp() {
+  }
+
+  void testInstance();
+};
+
+
+CPPUNIT_TEST_SUITE_REGISTRATION( SingletonHolderTest );
+
+class M {
+private:
+  string _greeting;
+public:
+  M(const string& greeting):_greeting(greeting) {}
+
+  const string& greeting() const { return _greeting; }
+
+  void greeting(const string& greeting) {
+    _greeting = greeting;
+  }
+};
+
+typedef SharedHandle<M> MHandle;
+typedef SharedHandle<int> IntHandle;
+
+void SingletonHolderTest::testInstance()
+{
+  MHandle m = new M("Hello world.");
+  SingletonHolder<MHandle>::instance(m);
+
+  cerr << SingletonHolder<MHandle>::instance()->greeting() << endl;
+
+  SingletonHolder<MHandle>::instance()->greeting("Yes, it worked!");
+
+  cerr << SingletonHolder<MHandle>::instance()->greeting() << endl;
+
+  IntHandle i = new int(100);
+  SingletonHolder<IntHandle>::instance(i);
+  cerr << SingletonHolder<IntHandle>::instance() << endl;
+
+  cerr << SingletonHolder<MHandle>::instance()->greeting() << endl;
+
+}
diff --git a/test/malformed.netrc b/test/malformed.netrc
new file mode 100644
index 00000000..2d27e03e
--- /dev/null
+++ b/test/malformed.netrc
@@ -0,0 +1,4 @@
+machine host2
+login aria2
+password aria2password
+account
diff --git a/test/sample.netrc b/test/sample.netrc
index 84328d91..4df1a244 100644
--- a/test/sample.netrc
+++ b/test/sample.netrc
@@ -2,13 +2,12 @@ machine host1
 login tujikawa
 password tujikawapassword
 account tujikawaaccount
+macdef init
+cd /home/aria2 machine
 
 machine host2
 login aria2
 password aria2password
 account aria2account
 
-default
-login anonymous
-password ARIA2@USER
-account ARIA2@ACCT
\ No newline at end of file
+default login anonymous password ARIA2@USER account ARIA2@ACCT
\ No newline at end of file