<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -19,42 +19,102 @@ class EpiTwitter extends EpiOAuth
   protected $authorizeUrl   = 'http://twitter.com/oauth/authorize';
   protected $authenticateUrl= 'http://twitter.com/oauth/authenticate';
   protected $apiUrl         = 'http://twitter.com';
+  protected $apiVersionedUrl= 'http://api.twitter.com';
   protected $searchUrl      = 'http://search.twitter.com';
   protected $userAgent      = 'EpiTwitter (http://github.com/jmathai/twitter-async/tree/)';
+  protected $apiVersion     = '1';
+  protected $isAsynchronous = false;
+
+  /* OAuth methods */
+  public function delete($endpoint, $params = null)
+  {
+    return $this-&gt;request('DELETE', $endpoint, $params);
+  }
+
+  public function get($endpoint, $params = null)
+  {
+    return $this-&gt;request('GET', $endpoint, $params);
+  }
+
+  public function post($endpoint, $params = null)
+  {
+    return $this-&gt;request('POST', $endpoint, $params);
+  }
+
+  /* Basic auth methods */
+  public function delete_basic($endpoint, $params = null, $username = null, $password = null)
+  {
+    return $this-&gt;request_basic('DELETE', $endpoint, $params, $username, $password);
+  }
+
+  public function get_basic($endpoint, $params = null, $username = null, $password = null)
+  {
+    return $this-&gt;request_basic('GET', $endpoint, $params, $username, $password);
+  }
+
+  public function post_basic($endpoint, $params = null, $username = null, $password = null)
+  {
+    return $this-&gt;request_basic('POST', $endpoint, $params, $username, $password);
+  }
+
+  public function useApiVersion($version = null)
+  {
+    $this-&gt;apiVersion = $version;
+  }
+
+  public function useAsynchronous($async = true)
+  {
+    $this-&gt;isAsynchronous = (bool)$async;
+  }
+
+  public function __construct($consumerKey = null, $consumerSecret = null, $oauthToken = null, $oauthTokenSecret = null)
+  {
+    parent::__construct($consumerKey, $consumerSecret, self::EPITWITTER_SIGNATURE_METHOD);
+    $this-&gt;setToken($oauthToken, $oauthTokenSecret);
+  }
 
   public function __call($name, $params = null/*, $username, $password*/)
   {
     $parts  = explode('_', $name);
     $method = strtoupper(array_shift($parts));
     $parts  = implode('_', $parts);
-    $path   = '/' . preg_replace('/[A-Z]|[0-9]+/e', &quot;'/'.strtolower('\\0')&quot;, $parts) . '.json';
+    $endpoint   = '/' . preg_replace('/[A-Z]|[0-9]+/e', &quot;'/'.strtolower('\\0')&quot;, $parts) . '.json';
+    /* HACK: this is required for list support that starts with a user id */
+    $endpoint = str_replace('//','/',$endpoint);
     $args = !empty($params) ? array_shift($params) : null;
 
     // calls which do not have a consumerKey are assumed to not require authentication
     if($this-&gt;consumerKey === null)
     {
-      $query = !is_null($args) ? http_build_query($args, '', '&amp;') : '';
-      $url = (preg_match('@^/(search|trends)@', $path) ? $this-&gt;searchUrl : $this-&gt;apiUrl) . &quot;{$path}?{$query}&quot;;
-      $ch  = curl_init($url);
-      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
-      curl_setopt($ch, CURLOPT_TIMEOUT, $this-&gt;requestTimeout);
-      curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
       if(!empty($params))
       {
         $username = array_shift($params);
         $password = !empty($params) ? array_shift($params) : null;
-        if($username !== null &amp;&amp; $password !== null)
-          curl_setopt($ch, CURLOPT_USERPWD, &quot;{$username}:{$password}&quot;);
       }
 
-      return new EpiTwitterJson(EpiCurl::getInstance()-&gt;addCurl($ch), self::EPITWITTER_AUTH_BASIC);
+      return $this-&gt;request_basic($method, $endpoint, $args, $username, $password);
     }
 
+    return $this-&gt;request($method, $endpoint, $args);
+  }
+
+  private function getApiUrl($endpoint)
+  {
+    if(preg_match('@^/(search|trends)@', $endpoint))
+      return &quot;{$this-&gt;searchUrl}{$endpoint}&quot;;
+    elseif(!empty($this-&gt;apiVersion))
+      return &quot;{$this-&gt;apiVersionedUrl}/{$this-&gt;apiVersion}{$endpoint}&quot;;
+    else
+      return &quot;{$this-&gt;apiUrl}{$endpoint}&quot;;
+  }
+
+  private function request($method, $endpoint, $params = null)
+  {
     // parse the keys to determine if this should be multipart
     $isMultipart = false;
-    if($args)
+    if($params)
     {
-      foreach($args as $k =&gt; $v)
+      foreach($params as $k =&gt; $v)
       {
         if(strncmp('@',$k,1) === 0)
         {
@@ -64,26 +124,45 @@ class EpiTwitter extends EpiOAuth
       }
     }
 
-    $url = $this-&gt;getUrl(&quot;{$this-&gt;apiUrl}{$path}&quot;);
-    return new EpiTwitterJson(call_user_func(array($this, 'httpRequest'), $method, $url, $args, $isMultipart));
+    $url = $this-&gt;getUrl($this-&gt;getApiUrl($endpoint));
+    $resp= new EpiTwitterJson(call_user_func(array($this, 'httpRequest'), $method, $url, $params, $isMultipart), $this-&gt;debug);
+    if(!$this-&gt;isAsynchronous)
+      $resp-&gt;responseText;
+
+    return $resp;
   }
 
-  public function __construct($consumerKey = null, $consumerSecret = null, $oauthToken = null, $oauthTokenSecret = null)
+  private function request_basic($method, $endpoint, $params = null, $username = null, $password = null)
   {
-    parent::__construct($consumerKey, $consumerSecret, self::EPITWITTER_SIGNATURE_METHOD);
-    $this-&gt;setToken($oauthToken, $oauthTokenSecret);
+    $url = $this-&gt;getApiUrl($endpoint);
+    if($method === 'GET')
+      $url .= is_null($params) ? '' : '?'.http_build_query($params, '', '&amp;');
+    $ch  = curl_init($url);
+    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
+    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+    curl_setopt($ch, CURLOPT_TIMEOUT, $this-&gt;requestTimeout);
+    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
+    if($method === 'POST' &amp;&amp; $params !== null)
+      curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
+    if(!empty($username) &amp;&amp; !empty($password))
+      curl_setopt($ch, CURLOPT_USERPWD, &quot;{$username}:{$password}&quot;);
+
+    $resp = new EpiTwitterJson(EpiCurl::getInstance()-&gt;addCurl($ch), $this-&gt;debug);
+    if(!$this-&gt;isAsynchronous)
+      $resp-&gt;responseText;
+
+    return $resp;
   }
 }
 
 class EpiTwitterJson implements ArrayAccess, Countable, IteratorAggregate
 {
+  private $debug;
   private $__resp;
-  private $__auth = EpiTwitter::EPITWITTER_AUTH_OAUTH;
-  public function __construct($response, $auth = null)
+  public function __construct($response, $debug = false)
   {
     $this-&gt;__resp = $response;
-    if($auth !== null)
-      $this-&gt;__auth = $auth;
+    $this-&gt;debug  = $debug;
   }
 
   // ensure that calls complete by blocking for results, NOOP if already returned
@@ -131,19 +210,11 @@ class EpiTwitterJson implements ArrayAccess, Countable, IteratorAggregate
 
   public function __get($name)
   {
-    if(($this-&gt;__resp-&gt;code &lt; 200 || $this-&gt;__resp-&gt;code &gt;= 400) &amp;&amp; $name !== 'responseText' &amp;&amp; $name !== 'headers') // TODO: clean up
-    {
-      switch($this-&gt;__auth)
-      {
-        case EpiTwitter::EPITWITTER_AUTH_OAUTH:
-          EpiOAuthException::raise($this-&gt;__resp-&gt;data, $this-&gt;__resp-&gt;code);
-        case EpiTwitter::EPITWITTER_AUTH_BASIC:
-          throw new EpiTwitterException($this-&gt;__resp-&gt;data, $this-&gt;__resp-&gt;code);
-        default:
-          throw new Exception(&quot;Unknown EpiTwitter Exception.  Response: {$this-&gt;__resp-&gt;data}&quot;, $this-&gt;__resp-&gt;code);
-      }
-    }
+    $accessible = array('responseText'=&gt;1,'headers'=&gt;1);
+    if(($this-&gt;__resp-&gt;code &lt; 200 || $this-&gt;__resp-&gt;code &gt;= 400) &amp;&amp; !isset($accessible[$name]))
+      EpiTwitterException::raise($this-&gt;__resp, $this-&gt;debug);
 
+    // if no exception is thrown, continue
     $this-&gt;responseText = $this-&gt;__resp-&gt;data;
     $this-&gt;code         = $this-&gt;__resp-&gt;code;
     $this-&gt;headers      = $this-&gt;__resp-&gt;headers;
@@ -168,4 +239,28 @@ class EpiTwitterJson implements ArrayAccess, Countable, IteratorAggregate
   }
 }
 
-class EpiTwitterException extends Exception {}
+class EpiTwitterException extends EpiException 
+{
+  public static function raise($response, $debug)
+  {
+    $message = $response-&gt;data;
+ 
+    switch($response-&gt;code)
+    {
+      case 400:
+        throw new EpiTwitterBadRequestException($message, $response-&gt;code);
+      case 401:
+        throw new EpiTwitterNotAuthorizedException($message, $response-&gt;code);
+      case 403:
+        throw new EpiTwitterForbiddenException($message, $response-&gt;code);
+      case 404:
+        throw new EpiTwitterNotFoundException($message, $response-&gt;code);
+      default:
+        throw new EpiTwitterException($message, $response-&gt;code);
+    }
+  }
+}
+class EpiTwitterBadRequestException extends EpiTwitterException{}
+class EpiTwitterNotAuthorizedException extends EpiTwitterException{}
+class EpiTwitterForbiddenException extends EpiTwitterException{}
+class EpiTwitterNotFoundException extends EpiTwitterException{}</diff>
      <filename>EpiTwitter.php</filename>
    </modified>
    <modified>
      <diff>@@ -16,6 +16,7 @@ class EpiTwitterTest extends PHPUnit_Framework_TestCase
     $this-&gt;twitterObj = new EpiTwitter($consumer_key, $consumer_secret, $token, $secret);
     $this-&gt;twitterObjUnAuth = new EpiTwitter($consumer_key, $consumer_secret);
     $this-&gt;twitterObjBasic = new EpiTwitter();
+    $this-&gt;twitterObjBadAuth = new EpiTwitter('foo', 'bar', 'foo', 'bar');
     $this-&gt;id = '25451974';
     $this-&gt;screenName = 'jmathai_test';
     $this-&gt;twitterUsername = 'jmathai_test';
@@ -53,6 +54,10 @@ class EpiTwitterTest extends PHPUnit_Framework_TestCase
 
   function testBooleanResponse()
   {
+    $resp = $this-&gt;twitterObj-&gt;get('/friendships/exists.json', array('user_a' =&gt; 'jmathai_test','user_b' =&gt; 'jmathai'));
+    $this-&gt;assertTrue(gettype($resp-&gt;response) === 'boolean', 'response should be a boolean for friendship exists');
+    $this-&gt;assertTrue($resp-&gt;response, 'response should be true for friendship exists');
+    // __call
     $resp = $this-&gt;twitterObj-&gt;get_friendshipsExists(array('user_a' =&gt; 'jmathai_test','user_b' =&gt; 'jmathai'));
     $this-&gt;assertTrue(gettype($resp-&gt;response) === 'boolean', 'response should be a boolean for friendship exists');
     $this-&gt;assertTrue($resp-&gt;response, 'response should be true for friendship exists');
@@ -60,6 +65,12 @@ class EpiTwitterTest extends PHPUnit_Framework_TestCase
 
   function testGetVerifyCredentials()
   {
+    $resp = $this-&gt;twitterObj-&gt;get('/account/verify_credentials.json');
+    $this-&gt;assertTrue(strlen($resp-&gt;responseText) &gt; 0, 'responseText was empty');
+    $this-&gt;assertTrue($resp instanceof EpiTwitterJson, 'response is not an array');
+    $this-&gt;assertTrue(!empty($resp-&gt;screen_name), 'member property screen_name is empty');
+    $this-&gt;assertFalse($resp-&gt;protected, 'protected is not false');
+    // __call
     $resp = $this-&gt;twitterObj-&gt;get_accountVerify_credentials();
     $this-&gt;assertTrue(strlen($resp-&gt;responseText) &gt; 0, 'responseText was empty');
     $this-&gt;assertTrue($resp instanceof EpiTwitterJson, 'response is not an array');
@@ -69,12 +80,24 @@ class EpiTwitterTest extends PHPUnit_Framework_TestCase
 
   function testGetWithParameters()
   {
+    $resp = $this-&gt;twitterObj-&gt;get('/statuses/friends_timeline.json', array('since_id' =&gt; 1));
+    $this-&gt;assertTrue(!empty($resp-&gt;response[0]['user']['screen_name']), 'first status has no screen name');
+    // __call
     $resp = $this-&gt;twitterObj-&gt;get_statusesFriends_timeline(array('since_id' =&gt; 1));
     $this-&gt;assertTrue(!empty($resp-&gt;response[0]['user']['screen_name']), 'first status has no screen name');
   }
 
   function testGetFollowers()
   {
+    $resp = $this-&gt;twitterObj-&gt;get('/statuses/followers.json');
+    $this-&gt;assertTrue(count($resp) &gt; 0, 'Count of followers is not greater than 0');
+    $this-&gt;assertTrue(!empty($resp[0]), 'array access for resp is empty');
+    foreach($resp as $k =&gt; $v)
+    {
+      $this-&gt;assertTrue(!empty($v-&gt;screen_name), 'screen name for one of the resp nodes is empty');
+    }
+    $this-&gt;assertTrue($k &gt; 0, 'test did not properly loop over followers');
+    // __call
     $resp = $this-&gt;twitterObj-&gt;get_statusesFollowers();
     $this-&gt;assertTrue(count($resp) &gt; 0, 'Count of followers is not greater than 0');
     $this-&gt;assertTrue(!empty($resp[0]), 'array access for resp is empty');
@@ -88,6 +111,19 @@ class EpiTwitterTest extends PHPUnit_Framework_TestCase
   function testPostStatus()
   {
     $statusText = 'Testing really weird chars &quot;~!@#$%^&amp;*()-+\[]{}:\'&gt;?&lt;&#8776;&#231;&#8706;&#180;&#223;&#169;&#402;&#729;&#729;&#8747;&#8730;&#8730;&#402;&#402;&#8706;&#8706;&#8224;&#165;&#8710;&#8710;&#8710; (time: ' . time() . ')';
+    $resp = $this-&gt;twitterObj-&gt;post('/statuses/update.json', array('status' =&gt; $statusText));
+    $this-&gt;assertEquals($resp-&gt;text, str_replace(array('&lt;','&gt;'),array('&amp;lt;','&amp;gt;'),$statusText), 'The status was not updated correctly');
+    
+    $statusText = 'Testing a random status (time: ' . time() . ')';
+    $resp = $this-&gt;twitterObj-&gt;post('/statuses/update.json', array('status' =&gt; $statusText));
+    $this-&gt;assertEquals($resp-&gt;text, $statusText, 'The status was not updated correctly');
+    // reply to it
+    $statusText = 'Testing a random status with reply to id (reply to: ' . $resp-&gt;id . ')';
+    $resp = $this-&gt;twitterObj-&gt;post('/statuses/update.json', array('status' =&gt; $statusText, 'in_reply_to_status_id' =&gt; &quot;{$resp-&gt;id}&quot;));
+    $this-&gt;assertEquals($resp-&gt;text, $statusText, 'The status with reply to id was not updated correctly');
+    
+    // __call
+    $statusText = 'Testing really weird chars &quot;~!@#$%^&amp;*()-+\[]{}:\'&gt;?&lt;&#8776;&#231;&#8706;&#180;&#223;&#169;&#402;&#729;&#729;&#8747;&#8730;&#8730;&#402;&#402;&#8706;&#8706;&#8224;&#165;&#8710;&#8710;&#8710; (time: ' . time() . ')';
     $resp = $this-&gt;twitterObj-&gt;post_statusesUpdate(array('status' =&gt; $statusText));
     $this-&gt;assertEquals($resp-&gt;text, str_replace(array('&lt;','&gt;'),array('&amp;lt;','&amp;gt;'),$statusText), 'The status was not updated correctly');
     
@@ -103,12 +139,19 @@ class EpiTwitterTest extends PHPUnit_Framework_TestCase
   function testPostStatusUnicode()
   {
     $statusText = 'Testing a random status with unicode &#1489;&#1493;&#1511;&#1512; &#1496;&#1493;&#1489; (' . time() . ')';
+    $resp = $this-&gt;twitterObj-&gt;post('/statuses/update.json', array('status' =&gt; $statusText));
+    $this-&gt;assertEquals($resp-&gt;text, $statusText, 'The status was not updated correctly');
+    // __call
+    $statusText = 'Testing a random status with unicode &#1489;&#1493;&#1511;&#1512; &#1496;&#1493;&#1489; (' . time() . ')';
     $resp = $this-&gt;twitterObj-&gt;post_statusesUpdate(array('status' =&gt; $statusText));
     $this-&gt;assertEquals($resp-&gt;text, $statusText, 'The status was not updated correctly');
   }
 
   function testDirectMessage()
   {
+    $resp = $this-&gt;twitterObj-&gt;post('/direct_messages/new.json',  array ( 'user' =&gt; $this-&gt;screenName, 'text' =&gt; &quot;@username that's dirt cheap man, good looking out. I shall buy soon.You still play Halo at all?&quot;));
+    $this-&gt;assertTrue(!empty($resp-&gt;response['id']), &quot;response id is empty&quot;);
+    // __call
     $resp = $this-&gt;twitterObj-&gt;post_direct_messagesNew( array ( 'user' =&gt; $this-&gt;screenName, 'text' =&gt; &quot;@username that's dirt cheap man, good looking out. I shall buy soon.You still play Halo at all?&quot;));
     $this-&gt;assertTrue(!empty($resp-&gt;response['id']), &quot;response id is empty&quot;);
   }
@@ -121,18 +164,17 @@ class EpiTwitterTest extends PHPUnit_Framework_TestCase
     $this-&gt;assertEquals($token-&gt;oauth_token, substr($authenticateUrl, (strpos($authenticateUrl, '=')+1)), &quot;token does not equal the one which was passed in&quot;);
   }
 
-  /**
-  * @expectedException EpiOAuthException
-  */
-  function testNoRequiredParameter()
-  {
-    $resp = $this-&gt;twitterObj-&gt;post_direct_messagesNew( array ( 'user' =&gt; $this-&gt;screenName, 'text' =&gt; ''));
-    $this-&gt;assertTrue(!empty($resp-&gt;response['error']), &quot;An empty direct message should return an error message&quot;);
-
-  }
-
   function testResponseAccess()
   {
+    $resp = $this-&gt;twitterObj-&gt;get('/statuses/followers.json');
+    $this-&gt;assertTrue(!empty($resp[0]), 'array access for resp is empty');
+    $this-&gt;assertEquals($resp[0], $resp-&gt;response[0], 'array access for resp is empty');
+    foreach($resp as $k =&gt; $v)
+    {
+      $this-&gt;assertTrue(!empty($v-&gt;screen_name), 'screen name for one of the resp nodes is empty');
+    }
+    $this-&gt;assertTrue($k &gt; 0, 'test did not properly loop over followers');
+    // __call
     $resp = $this-&gt;twitterObj-&gt;get_statusesFollowers();
     $this-&gt;assertTrue(!empty($resp[0]), 'array access for resp is empty');
     $this-&gt;assertEquals($resp[0], $resp-&gt;response[0], 'array access for resp is empty');
@@ -145,6 +187,13 @@ class EpiTwitterTest extends PHPUnit_Framework_TestCase
 
   function testSearch()
   {
+    $resp = $this-&gt;twitterObjBasic-&gt;get_basic('/search.json', array('q' =&gt; 'hello'));
+    $this-&gt;assertTrue(is_array($resp-&gt;response['results']));
+    $this-&gt;assertTrue(!empty($resp-&gt;results[0]-&gt;text), &quot;search response is not an array {$resp-&gt;results[0]-&gt;text}&quot;);
+    $resp = $this-&gt;twitterObjBasic-&gt;get_basic('/search.json', array('geocode' =&gt; '40.757929,-73.985506,25km', 'rpp' =&gt; 10));
+    $this-&gt;assertTrue(is_array($resp-&gt;response['results']));
+    $this-&gt;assertTrue(!empty($resp-&gt;results[0]-&gt;text), &quot;search response is not an array {$resp-&gt;results[0]-&gt;text}&quot;);
+    // __call
     $resp = $this-&gt;twitterObjBasic-&gt;get_search(array('q' =&gt; 'hello'));
     $this-&gt;assertTrue(is_array($resp-&gt;response['results']));
     $this-&gt;assertTrue(!empty($resp-&gt;results[0]-&gt;text), &quot;search response is not an array {$resp-&gt;results[0]-&gt;text}&quot;);
@@ -155,6 +204,13 @@ class EpiTwitterTest extends PHPUnit_Framework_TestCase
 
   function testTrends()
   {
+    $resp = $this-&gt;twitterObjBasic-&gt;get('/trends.json');
+    $this-&gt;assertTrue(is_array($resp-&gt;response['trends']), &quot;trends is empty&quot;);
+    $this-&gt;assertTrue(!empty($resp-&gt;trends[0]-&gt;name), &quot;current trends is not an array &quot; . $resp-&gt;trends[0]-&gt;name);
+
+    $resp = $this-&gt;twitterObjBasic-&gt;get('/trends/current.json');
+    $this-&gt;assertTrue(is_array($resp-&gt;response['trends']), &quot;current trends is empty&quot;);
+    // __call
     $resp = $this-&gt;twitterObjBasic-&gt;get_trends();
     $this-&gt;assertTrue(is_array($resp-&gt;response['trends']), &quot;trends is empty&quot;);
     $this-&gt;assertTrue(!empty($resp-&gt;trends[0]-&gt;name), &quot;current trends is not an array &quot; . $resp-&gt;trends[0]-&gt;name);
@@ -165,6 +221,14 @@ class EpiTwitterTest extends PHPUnit_Framework_TestCase
 
   function testBasicAuth()
   {
+    $resp = $this-&gt;twitterObjBasic-&gt;get_basic('/account/verify_credentials.json', null, $this-&gt;twitterUsername, $this-&gt;twitterPassword);
+    $this-&gt;assertEquals($resp-&gt;screen_name, $this-&gt;screenName, &quot;Screenname from response is not {$this-&gt;screenName} when using get_basic&quot;);
+    $status = 'Basic auth status update ' . time();
+    $resp = $this-&gt;twitterObjBasic-&gt;post_basic('/statuses/update.json', array('status' =&gt; $status), $this-&gt;twitterUsername, $this-&gt;twitterPassword);
+    $this-&gt;assertEquals(200, $resp-&gt;code, &quot;Status update response code was not 200&quot;);
+    $newStatus = $this-&gt;twitterObjBasic-&gt;get_basic('/statuses/show.json', array('id' =&gt; $resp-&gt;id));
+    $this-&gt;assertEquals($status, $newStatus-&gt;text, &quot;Updated status is not what it should be&quot;);
+    // testing __call
     $resp = $this-&gt;twitterObjBasic-&gt;get_accountVerify_credentials(null, $this-&gt;twitterUsername, $this-&gt;twitterPassword);
     $this-&gt;assertEquals($resp-&gt;screen_name, $this-&gt;screenName, &quot;Screenname from response is not {$this-&gt;screenName}&quot;);
     $status = 'Basic auth status update ' . time();
@@ -177,6 +241,13 @@ class EpiTwitterTest extends PHPUnit_Framework_TestCase
   function testSSl()
   {
     $this-&gt;twitterObj-&gt;useSSL(true);
+    $resp = $this-&gt;twitterObj-&gt;get('/account/verify_credentials.json');
+    $this-&gt;assertTrue(strlen($resp-&gt;responseText) &gt; 0, 'responseText was empty');
+    $this-&gt;assertTrue($resp instanceof EpiTwitterJson, 'response is not an array');
+    $this-&gt;assertTrue(!empty($resp-&gt;screen_name), 'member property screen_name is empty');
+    $this-&gt;twitterObj-&gt;useSSL(false);
+    // __call
+    $this-&gt;twitterObj-&gt;useSSL(true);
     $resp = $this-&gt;twitterObj-&gt;get_accountVerify_credentials();
     $this-&gt;assertTrue(strlen($resp-&gt;responseText) &gt; 0, 'responseText was empty');
     $this-&gt;assertTrue($resp instanceof EpiTwitterJson, 'response is not an array');
@@ -187,6 +258,11 @@ class EpiTwitterTest extends PHPUnit_Framework_TestCase
   function testCount()
   {
     $screenName = ucwords(strtolower($this-&gt;screenName));
+    $resp = $this-&gt;twitterObj-&gt;get(&quot;/statuses/followers/{$screenName}.json&quot;);
+    $this-&gt;assertTrue(count($resp) &gt; 0, &quot;Count for followers was not larger than 0&quot;);
+    $resp = $this-&gt;twitterObj-&gt;get(&quot;/statuses/followers/{$screenName}.json&quot;, array('page' =&gt; 100));
+    $this-&gt;assertTrue(count($resp) == 0, &quot;Page 100 should return a count of 0&quot;);
+    // __call
     $method = &quot;get_statusesFollowers{$screenName}&quot;;
     $resp = $this-&gt;twitterObj-&gt;$method();
     $this-&gt;assertTrue(count($resp) &gt; 0, &quot;Count for followers was not larger than 0&quot;);
@@ -197,11 +273,12 @@ class EpiTwitterTest extends PHPUnit_Framework_TestCase
   function testUpdateAvatar()
   {
     $file = dirname(__FILE__) . '/avatar_test_image.jpg';
-    $resp = $this-&gt;twitterObj-&gt;post_accountUpdate_profile_image(array('@image' =&gt; &quot;@{$file}&quot;));
+    $resp = $this-&gt;twitterObj-&gt;post('/account/update_profile_image.json', array('@image' =&gt; &quot;@{$file}&quot;));
     // api seems to be a bit behind and doesn't respond with the new image url - use code instead for now
     $this-&gt;assertEquals($resp-&gt;code, 200, 'Response code was not 200');
 
-    $file = dirname(__FILE__) . '/avatar_test_image.png';
+    // __call
+    $file = dirname(__FILE__) . '/avatar_test_image.jpg';
     $resp = $this-&gt;twitterObj-&gt;post_accountUpdate_profile_image(array('@image' =&gt; &quot;@{$file}&quot;));
     // api seems to be a bit behind and doesn't respond with the new image url - use code instead for now
     $this-&gt;assertEquals($resp-&gt;code, 200, 'Response code was not 200');
@@ -210,29 +287,35 @@ class EpiTwitterTest extends PHPUnit_Framework_TestCase
   function testUpdateBackground()
   {
     $file = dirname(__FILE__) . '/avatar_test_image.jpg';
-    $resp = $this-&gt;twitterObj-&gt;post_accountUpdate_profile_background_image(array('@image' =&gt; &quot;@{$file}&quot;));
+    $resp = $this-&gt;twitterObj-&gt;post('/account/update_profile_background_image.json', array('@image' =&gt; &quot;@{$file}&quot;, 'tile' =&gt; 'true'));
     // api seems to be a bit behind and doesn't respond with the new image url - use code instead for now
     $this-&gt;assertEquals($resp-&gt;code, 200, 'Response code was not 200');
 
+    // __call
     $file = dirname(__FILE__) . '/avatar_test_image.jpg';
-    $resp = $this-&gt;twitterObj-&gt;post_accountUpdate_profile_background_image(array('@image' =&gt; &quot;@{$file}&quot;, 'tile' =&gt; 'true'));
-    // api seems to be a bit behind and doesn't respond with the new image url - use code instead for now
-    $this-&gt;assertEquals($resp-&gt;code, 200, 'Response code was not 200');
-
-    $file = dirname(__FILE__) . '/avatar_test_image.png';
     $resp = $this-&gt;twitterObj-&gt;post_accountUpdate_profile_background_image(array('@image' =&gt; &quot;@{$file}&quot;));
     // api seems to be a bit behind and doesn't respond with the new image url - use code instead for now
     $this-&gt;assertEquals($resp-&gt;code, 200, 'Response code was not 200');
-
-    $file = dirname(__FILE__) . '/avatar_test_image.png';
-    $resp = $this-&gt;twitterObj-&gt;post_accountUpdate_profile_background_image(array('@image' =&gt; &quot;@{$file}&quot;, 'tile' =&gt; 'true'));
-    // api seems to be a bit behind and doesn't respond with the new image url - use code instead for now
-    $this-&gt;assertEquals($resp-&gt;code, 200, 'Response code was not 200');
   }
 
   function testCreateFriendship()
   {
     // check if friendship exists
+    $exists = $this-&gt;twitterObj-&gt;get('/friendships/exists.json', array('user_a' =&gt; $this-&gt;screenName, 'user_b' =&gt; 'pbct_test'));
+    if($exists-&gt;response)
+    {
+      $destroy = $this-&gt;twitterObj-&gt;post('/friendships/destroy.json', array('id' =&gt; 'pbct_test'));
+      $destroy-&gt;responseText;
+    }
+
+    // perform checks now that env is set up
+    $exists = $this-&gt;twitterObj-&gt;get('/friendships/exists.json', array('user_a' =&gt; $this-&gt;screenName, 'user_b' =&gt; 'pbct_test'));
+    $this-&gt;assertFalse($exists-&gt;response, 'Friendship already exists and should not for create test');
+    $create = $this-&gt;twitterObj-&gt;post('/friendships/create.json', array('id' =&gt; 'pbct_test'));
+    $this-&gt;assertTrue($create-&gt;id &gt; 0, 'ID is empty from create friendship call');
+
+    // __call
+    // check if friendship exists
     $exists = $this-&gt;twitterObj-&gt;get_friendshipsExists(array('user_a' =&gt; $this-&gt;screenName, 'user_b' =&gt; 'pbct_test'));
     if($exists-&gt;response)
     {
@@ -250,6 +333,21 @@ class EpiTwitterTest extends PHPUnit_Framework_TestCase
   function testDestroyFriendship()
   {
     // check if friendship exists
+    $exists = $this-&gt;twitterObj-&gt;get('/friendships/exists.json', array('user_a' =&gt; $this-&gt;screenName, 'user_b' =&gt; 'pbct_test'));
+    if(!$exists-&gt;response)
+    {
+      $create = $this-&gt;twitterObj-&gt;post('/friendships/create.json', array('id' =&gt; 'pbct_test'));
+      $create-&gt;responseText;
+    }
+    
+    // perform checks now that env is set up
+    $exists = $this-&gt;twitterObj-&gt;get('/friendships/exists.json', array('user_a' =&gt; $this-&gt;screenName, 'user_b' =&gt; 'pbct_test'));
+    $this-&gt;assertTrue($exists-&gt;response, 'Friendship does not exist to be destroyed');
+    $destroy = $this-&gt;twitterObj-&gt;post('/friendships/destroy.json', array('id' =&gt; 'pbct_test'));
+    $this-&gt;assertTrue($destroy-&gt;id &gt; 0, 'ID is empty from destroy friendship call');
+
+    //__call
+    // check if friendship exists
     $exists = $this-&gt;twitterObj-&gt;get_friendshipsExists(array('user_a' =&gt; $this-&gt;screenName, 'user_b' =&gt; 'pbct_test'));
     if(!$exists-&gt;response)
     {
@@ -263,9 +361,18 @@ class EpiTwitterTest extends PHPUnit_Framework_TestCase
     $destroy = $this-&gt;twitterObj-&gt;post_friendshipsDestroy(array('id' =&gt; 'pbct_test'));
     $this-&gt;assertTrue($destroy-&gt;id &gt; 0, 'ID is empty from destroy friendship call');
   }
-  
+
   function testGetFriendsIds()
   {
+    $twitterFriends = $this-&gt;twitterObj-&gt;get('/friends/ids.json', array('screen_name' =&gt; $this-&gt;screenName));
+    $this-&gt;assertTrue(count($twitterFriends-&gt;response) &gt; 0, 'Count of get friend ids is 0');;
+    $this-&gt;assertTrue(!empty($twitterFriends[0]), 'First result in get friend ids is empty');;
+
+    $twitterFriends = $this-&gt;twitterObj-&gt;get('/friends/ids.json', array('user_id' =&gt; $this-&gt;id));
+    $this-&gt;assertTrue(count($twitterFriends-&gt;response) &gt; 0, 'Count of get friend ids is 0');;
+    $this-&gt;assertTrue(!empty($twitterFriends[0]), 'First result in get friend ids is empty');;
+
+    // __call
     $twitterFriends = $this-&gt;twitterObj-&gt;get_friendsIds(array('screen_name' =&gt; $this-&gt;screenName));
     $this-&gt;assertTrue(count($twitterFriends-&gt;response) &gt; 0, 'Count of get friend ids is 0');;
     $this-&gt;assertTrue(!empty($twitterFriends[0]), 'First result in get friend ids is empty');;
@@ -274,9 +381,18 @@ class EpiTwitterTest extends PHPUnit_Framework_TestCase
     $this-&gt;assertTrue(count($twitterFriends-&gt;response) &gt; 0, 'Count of get friend ids is 0');;
     $this-&gt;assertTrue(!empty($twitterFriends[0]), 'First result in get friend ids is empty');;
   }
-  
+
   function testGetStatusesFriends()
   {
+    $twitterFriends = $this-&gt;twitterObj-&gt;get('/statuses/friends.json', array('screen_name' =&gt; $this-&gt;screenName));
+    $this-&gt;assertTrue(count($twitterFriends-&gt;response) &gt; 0, 'Count of get statuses friends is 0');;
+    $this-&gt;assertTrue(!empty($twitterFriends[0]), 'First result in get statuses friends is empty');;
+
+    $twitterFriends = $this-&gt;twitterObj-&gt;get('/statuses/friends.json', array('user_id' =&gt; $this-&gt;id));
+    $this-&gt;assertTrue(count($twitterFriends-&gt;response) &gt; 0, 'Count of get statuses friends is 0');;
+    $this-&gt;assertTrue(!empty($twitterFriends[0]), 'First result in get statuses friends is empty');;
+
+    // __call
     $twitterFriends = $this-&gt;twitterObj-&gt;get_statusesFriends(array('screen_name' =&gt; $this-&gt;screenName));
     $this-&gt;assertTrue(count($twitterFriends-&gt;response) &gt; 0, 'Count of get statuses friends is 0');;
     $this-&gt;assertTrue(!empty($twitterFriends[0]), 'First result in get statuses friends is empty');;
@@ -284,7 +400,15 @@ class EpiTwitterTest extends PHPUnit_Framework_TestCase
     $twitterFriends = $this-&gt;twitterObj-&gt;get_statusesFriends(array('user_id' =&gt; $this-&gt;id));
     $this-&gt;assertTrue(count($twitterFriends-&gt;response) &gt; 0, 'Count of get statuses friends is 0');;
     $this-&gt;assertTrue(!empty($twitterFriends[0]), 'First result in get statuses friends is empty');;
+  }
 
+  function testGetLists()
+  {
+    $method = &quot;get_{$this-&gt;id}Lists&quot;;
+    $resp = $this-&gt;twitterObj-&gt;get(&quot;/{$this-&gt;id}/lists.json&quot;);
+    $this-&gt;assertTrue(count($resp-&gt;lists) &gt; 0, 'List count not greater than 0');
+    $this-&gt;assertEquals($resp-&gt;lists[0]-&gt;id, 1900727, 'List name is not &quot;Test&quot;');
+    $this-&gt;assertEquals($resp-&gt;lists[0]-&gt;member_count, 1, 'List member count not equal to 1');
   }
 
   function testDestructor()
@@ -301,4 +425,62 @@ class EpiTwitterTest extends PHPUnit_Framework_TestCase
     $resp = $this-&gt;twitterObj-&gt;get_statusesFollowers();
     $this-&gt;assertTrue(!empty($resp-&gt;headers['Status']), 'header status response should not be empty');
   }
+
+  function testExceptionWithDebug()
+  {
+    $this-&gt;twitterObj-&gt;setDebug(false);
+    $resp = $this-&gt;twitterObj-&gt;post_direct_messagesNew( array ( 'user' =&gt; 'jaisen_does_not_exist_and_dont_create_or_this_will_break', 'text' =&gt; 'seriously'));
+
+    try
+    {
+      $resp-&gt;response;
+      $this-&gt;fail('Should throw a 404 for no user exists');
+    }
+    catch(EpiTwitterException $e)
+    {
+      $messageArr = json_decode($e-&gt;getMessage(), true);
+      $this-&gt;assertTrue(empty($messageArr['headers']), &quot;With debug off there should be no headers&quot;);
+    }
+
+    $this-&gt;twitterObj-&gt;setDebug(true);
+    $resp2 = $this-&gt;twitterObj-&gt;post_direct_messagesNew( array ( 'user' =&gt; 'jaisen_does_not_exist_and_dont_create_or_this_will_break', 'text' =&gt; 'seriously'));
+
+    try
+    {
+      $resp2-&gt;response;
+      $this-&gt;fail('Should throw a 404 for no user exists');
+    }
+    catch(EpiTwitterException $e)
+    {
+      $messageArr = json_decode($e-&gt;getMessage(), true);
+      $this-&gt;assertFalse(stristr($messageArr['headers']['Status'], '404 Not Found'), &quot;With debug off there should be no headers&quot;);
+    }
+  }
+
+  /**
+  * @expectedException EpiTwitterForbiddenException
+  */
+  function testNoRequiredParameter()
+  {
+    $resp = $this-&gt;twitterObj-&gt;post_direct_messagesNew( array ( 'user' =&gt; $this-&gt;screenName, 'text' =&gt; ''));
+    $this-&gt;assertTrue(!empty($resp-&gt;response['error']), &quot;An empty direct message should return an error message&quot;);
+  }
+
+  /**
+  * @expectedException EpiTwitterNotAuthorizedException
+  */
+  function testBadCredentials()
+  {
+    $resp = $this-&gt;twitterObjBadAuth-&gt;post_direct_messagesNew( array ( 'user' =&gt; $this-&gt;screenName, 'text' =&gt; 'hello world'));
+    $this-&gt;assertTrue(!empty($resp-&gt;response['error']), &quot;Bad credentials should return a not authorized exception&quot;);
+  }
+
+  /**
+  * @expectedException EpiTwitterNotFoundException
+  */
+  function testNonExistantUser()
+  {
+    $resp = $this-&gt;twitterObj-&gt;post_direct_messagesNew( array ( 'user' =&gt; 'jaisen_does_not_exist_and_dont_create_or_this_will_break', 'text' =&gt; 'seriously'));
+    $this-&gt;assertTrue(!empty($resp-&gt;response['error']), &quot;Sending a message to a user that doesn't exist should return a 404&quot;);
+  }
 }</diff>
      <filename>tests/EpiTwitterTest.php</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>5459a5862b832bb87c668d337f6255eff6bc74ad</id>
    </parent>
    <parent>
      <id>f9531a3130ff89bd61d9f4b394f318fb669febfd</id>
    </parent>
  </parents>
  <author>
    <name>Jaisen Mathai</name>
    <email>jaisen@jmathai.com</email>
  </author>
  <url>http://github.com/jmathai/twitter-async/commit/24e97816563b6c4afc8b0ff24ea646274832bfe3</url>
  <id>24e97816563b6c4afc8b0ff24ea646274832bfe3</id>
  <committed-date>2009-11-06T01:23:24-08:00</committed-date>
  <authored-date>2009-11-06T01:18:04-08:00</authored-date>
  <message>Merge branch '2.0'</message>
  <tree>2d626d9313c421bdcca8b9226a227760bc03f8da</tree>
  <committer>
    <name>Jaisen Mathai</name>
    <email>jaisen@jmathai.com</email>
  </committer>
</commit>
