diff --git a/tests/twitter_block.test b/tests/twitter_block.test
index feada32..bf67a89 100644
--- a/tests/twitter_block.test
+++ b/tests/twitter_block.test
@@ -41,16 +41,16 @@ class TwitterBlockTestCase extends DrupalWebTestCase {
     // Verify the default settings for block are processed.
     $this->assertFieldByName('blocks[twitter_block_default_block][region]', 'sidebar_first', t('Default Twitter block is enabled in first sidebar successfully verified.') );
 
-    // Verify that blocks are not shown
+    // Verify that blocks are not shown.
     $this->drupalGet('/');
     $this->assertNoRaw( t('Drupal Discussion on Twitter'), t('Default Twitter block test not found.'));
 
-    // Enable the Default block and verify
+    // Enable the Default block and verify.
     $this->drupalPost('admin/structure/block', array('blocks[twitter_block_default_block][region]' => 'sidebar_first'), t('Save blocks'));
     $this->drupalGet('/');
     $this->assertRaw( t('Drupal Discussion on Twitter'), t('Default Twitter block text found.'));
 
-    // Add a new twitter block
+    // Add a new twitter block.
     /*
     $string = $this->randomName();
     $delta = strtolower($string);
@@ -65,11 +65,11 @@ class TwitterBlockTestCase extends DrupalWebTestCase {
     // Find new block on settings page.
     $this->assertRaw($string, t('New Twitter block is configurable-String found.'));
 
-    // Verify new block is not shown
+    // Verify new block is not shown.
     $this->drupalGet('/');
     $this->assertNoRaw($string, "New Twitter block isn't enabled yet. Not found.");
 
-    // Enable new block and verify
+    // Enable new block and verify.
     $this->drupalPost('admin/structure/block', array("blocks[twitter_block_$delta][region]" => 'sidebar_first'), t('Save blocks'));
     $this->assertRaw($string, "New Twitter block is displayed.");
     // */
diff --git a/twitter.class.php b/twitter.class.php
index e757591..e8c3d68 100644
--- a/twitter.class.php
+++ b/twitter.class.php
@@ -31,13 +31,18 @@ class TwitterSearch {
   private $search_string;
   private $twitter_name;
 
+  // API
+  private $api;
+
   // The url including the encoded query
   public $url_query;
 
   public function __construct($config = array()) {
+    $this->url_query = 'http://search.twitter.com/search.json?';
     $this->search_type = $config['search_type'];
+    $this->api = in_array($this->search_type, array('getTweetsFrom')) ? 'rest' : 'search';
     
-    if ( $config['search_type'] == 'searchHashtag' ) {
+    if ($config['search_type'] == 'searchHashtag') {
       // We presume the search string is already validated. 
       $this->search_string = $config['search_string'];
     }
@@ -45,12 +50,13 @@ class TwitterSearch {
       $this->twitter_name = $config['search_string'];
     }
 
+    $count = ($this->api == 'rest') ? 'count' : 'rpp';
     // The number of tweets to return per page.
-    if ( !empty( $config['results_per_page']) ) {
-      $this->options['rpp'] = $config['results_per_page'];
+    if (!empty($config['results_per_page'])) {
+      $this->options[$count] = $config['results_per_page'];
     }
     else {
-      $this->options['rpp'] = variable_get('twitter_block_default_results_per_page', 15);
+      $this->options[$count] = variable_get('twitter_block_default_results_per_page', 15);
     }
 
     // Filter by language, but only if there is one set in the config.
@@ -63,7 +69,36 @@ class TwitterSearch {
    * Retrieve JSON encoded search results
    */
   public function getJSON() {
-    return call_user_func(array($this, $this->search_type)); 
+    $response = call_user_func(array($this, $this->search_type)); 
+    $return = array(
+      'status' => TRUE,
+      'results' => array(),
+      'debug' => $response,
+    );
+    if (empty($response)) {
+      $return['status'] = 'Empty response from Twitter.';
+    }
+    else {
+      $decoded = json_decode($response);
+      if (empty($decoded)) {
+        $return['status'] = 'Response from Twitter is not valid JSON data.';
+      }
+      elseif ($this->api == 'rest') {
+        $data = $decoded;
+      }
+      else {
+        $data = $decoded->results;
+      }
+      // An error from the API.
+      if (!empty($data->error)) {
+        $return['status'] = $data->error;
+      }
+      // Everything was ok.
+      else {
+        $return['results'] = $data;
+      }
+    }
+    return $return;
   }
 
   /**
@@ -72,7 +107,8 @@ class TwitterSearch {
    * @return string $json JSON encoded search response
    */
   private function getTweetsFrom() {
-    $this->options['q'] = "from:$this->twitter_name";
+    $this->options['screen_name'] = $this->twitter_name;
+    $this->url_query = 'http://api.twitter.com/1/statuses/user_timeline.json?';
     $json = $this->search();
     return $json;
   }
@@ -123,7 +159,7 @@ class TwitterSearch {
    * @return string JSON encoded search response.
    */
   function search() {
-    $this->url_query = 'http://search.twitter.com/search.json?' . drupal_http_build_query($this->options);
+    $this->url_query .= drupal_http_build_query($this->options);
     $ch = curl_init($this->url_query);
     
     // Applications must have a meaningful and unique User Agent. 
@@ -138,5 +174,8 @@ class TwitterSearch {
 
     return $twitter_data;
   }
+
+  function getApi() {
+    return $this->api;
+  }
 }
-?>
diff --git a/twitter_block.css b/twitter_block.css
index a81eac7..0850849 100644
--- a/twitter_block.css
+++ b/twitter_block.css
@@ -1,3 +1,7 @@
+/**
+ * @file
+ * Custom CSS for the Twitter block display.
+ */
 
 .twitter_block_user {
   display: block;
diff --git a/twitter_block.info b/twitter_block.info
index eb8d185..e3d237d 100644
--- a/twitter_block.info
+++ b/twitter_block.info
@@ -4,4 +4,5 @@ core = 7.x
 
 files[] = twitter.class.inc
 files[] = twitter_block.test
-files[] = twitter_block.css
+
+stylesheets[all][] = twitter_block.css
diff --git a/twitter_block.install b/twitter_block.install
index 05dfdaf..a35ba97 100644
--- a/twitter_block.install
+++ b/twitter_block.install
@@ -2,11 +2,11 @@
 
 /**
  * @file
- * Install, update and uninstal functions for the twitter_block module
+ * Install, update and uninstal functions for the twitter_block module.
  */
 
 /**
- * Implements hook_schema
+ * Implements hook_schema().
  */
 function twitter_block_schema() {
   $schema['twitter_block'] = array(
diff --git a/twitter_block.module b/twitter_block.module
index 679b5dc..0ce6c58 100644
--- a/twitter_block.module
+++ b/twitter_block.module
@@ -22,12 +22,13 @@ function twitter_block_menu() {
 }
 
 /**
- * Implements hook_permission()
+ * Implements hook_permission().
  */
 function twitter_block_permission() {
   return array(
     'administer twitter blocks' => array(
-      'title' => t('Administer Twitter Blocks')),
+      'title' => t('Administer Twitter Blocks'),
+    ),
   );
 }
 
@@ -38,8 +39,7 @@ function get_twitter_block_config($delta) {
   static $config;
   if (!isset($config[$delta])) {
     $result = db_query("SELECT search_type, search_string, default_title, results_per_page, lang" .
-                        " FROM {twitter_block} WHERE delta = :delta",
-                        array(':delta' => $delta));
+      " FROM {twitter_block} WHERE delta = :delta", array(':delta' => $delta));
 
     // @todo There can be only one?
     foreach ($result as $record) {
@@ -132,9 +132,9 @@ function twitter_block_block_configure($delta) {
     /**
      * More broken dynamic form bits...
     // only provide options for Search by User.
-    '#states' => array ( 'invisible' => array(
+    '#states' => array ('invisible' => array(
       ':input[name="public_timeline"]' => array('FALSE')),
-     ),
+    ),
  */
   );
   $form['twitter_block_' . $delta]['lang'] = array(
@@ -164,19 +164,19 @@ function twitter_block_block_configure($delta) {
  */
 function twitter_block_form_validate($element, &$form_state) {
   // Strip off the leading @.
-  if ( $element['search_type']['#value'] !== 'searchHashtag'
-        && strpos( $element['search_string']['#value'], '@' ) !== 0) {
-          //form_set_error( 'search_string', t('Twitter names should start with "@".') );
-          $element['search_string']['#value'] = substr($element['search_string']['#value'], 1);
+  if ($element['search_type']['#value'] !== 'searchHashtag'
+      && strpos($element['search_string']['#value'], '@') !== 0) {
+    //form_set_error('search_string', t('Twitter names should start with "@".') );
+    $element['search_string']['#value'] = substr($element['search_string']['#value'], 1);
   }
 
-  if ( !empty($element['results_per_page']['#value']) ) {
-    if ( !ctype_digit( $element['results_per_page']['#value']) ) {
-      form_set_error( 'results_per_page', t('The number of results must be an integer.'));
+  if (!empty($element['results_per_page']['#value']) ) {
+    if (!ctype_digit($element['results_per_page']['#value']) ) {
+      form_set_error('results_per_page', t('The number of results must be an integer.'));
     }
     // Twitter doesn't like to return more than 100 tweets.
     elseif ($element['results_per_page']['#value'] > 100) {
-    form_set_error( 'results_per_page', t("The Twitter API limits the number of tweets returned to 100 or less."));
+      form_set_error('results_per_page', t("The Twitter API limits the number of tweets returned to 100 or less."));
     }
   }
 }
@@ -209,35 +209,56 @@ function twitter_block_block_save($delta = '', $edit = array()) {
  * Implements hook_block_view().
  */
 function twitter_block_block_view($delta) {
-  module_load_include( 'php', 'twitter_block', 'twitter.class' );
-
+  // Load the configuration.
+  $config = get_twitter_block_config($delta);
 
+  // Define the configation.
   $block = array();
-  $config = get_twitter_block_config($delta);
+  $block['subject'] = t($config['default_title']);
+  $block['content'] = twitter_block_load_tweets($config);
 
-  $twitter = new TwitterSearch($config);
-  $twitter_reply = cache_get($cid = 'twitter_block_' . $delta, $bin = 'cache');
+  return $block;
+}
 
-    $block['subject'] = t($config['default_title']);
+/**
+ * Grab data from Twitter, store it for later.
+ * @param $config An array suitable for passing to the TwitterSearch object.
+ * @return Themed output.
+ */
+function twitter_block_load_tweets($config) {
+  module_load_include('php', 'twitter_block', 'twitter.class');
 
-  if ($twitter_reply == NULL) {
-      $twitter_reply = json_decode($twitter->getJSON());
-      if (!isset( $twitter_reply -> results) ) {
-    watchdog('Twitter Block', 'Recieved an unexpected reply from Twitter. ' .
-        'Perhaps just a fail whale? Our search url with query:<br/>' .
-        '@url_query', array( 'url_query' => $twitter -> url_query),
-        WATCHDOG_NOTICE);
-  }
-      else{
-      cache_set('twitter_block_' . $delta, $twitter_reply, 'cache', CACHE_TEMPORARY);
-      $block['content'] = theme('twitter_block', $twitter_reply -> results );
-      }
-  }
-  else{
-      $block['content'] = theme('twitter_block', $twitter_reply -> data ->results );
+  // We use the md5 of the block config as cache cid;
+  $cid = 'twitter_block_feed_' . md5(serialize($config));
+  $cache_bin = 'cache';
+
+  // Build the object.
+  $twitter = new TwitterSearch($config);
+
+  // We cache response even if it's empty so an empty response cannot cause a
+  // performance problem by making us contact twitter in every request
+  if ($cache = cache_get($cid, $cache_bin)) {
+    $results = $cache->data;
   }
+  else {
+    $response = $twitter->getJSON();
+    $results = array();
+    if (empty($response) || !is_array($response) || !isset($response['status']) || $response['status'] !== TRUE) {
+      watchdog('Twitter Block', 'Recieved an unexpected reply from Twitter. ' .
+        'Perhaps just a fail whale?<br/>' .
+        'URL: url_query<br />' .
+        'response', array('url_query' => $twitter->url_query, 'response' => print_r($response, TRUE)),
+        WATCHDOG_NOTICE);
+    }
+    else {
+      $results = $response['results'];
+    }
 
-  return $block;
+    // Save the data for later.
+    cache_set($cid, $results, $cache_bin, CACHE_TEMPORARY);
+  }
+ 
+  return theme('twitter_block', array('twitter_result' => $results, 'api' => $twitter->getApi()));
 }
 
 /**
@@ -245,33 +266,32 @@ function twitter_block_block_view($delta) {
  */
 function twitter_block_theme($existing, $type , $theme, $path) {
   return array(
-    'twitter_block' => array('variables' => array()),
-    'twitter_block_tweets' => array('variables' => array()),
+    'twitter_block' => array(
+    	'variables' => array('twitter_result' => NULL, 'api' => NULL),
+    ),
+    'twitter_block_tweets' =>array(
+    	'variables' => array('tweet' => NULL, 'api' => NULL),
+    ),
   );
 }
 
 /**
- * Implements hook_init().
+ * Returns themed html for individual tweets.
  */
-function twitter_block_init() {
-  drupal_add_css( drupal_get_path('module', 'twitter_block') . '/twitter_block.css');
-}
-
-/**
- * Returns themed html for individual tweets
- */
-function theme_twitter_block_tweets($tweet_object, $variables = array() ) {
-  $tweet = get_object_vars($tweet_object['tweet']);
-  $tweet['text'] = twitter_block_linkify($tweet['text']);
+function theme_twitter_block_tweets($variables) {
+  $tweet = $variables['tweet'];
+  $text = twitter_block_linkify($tweet->text);
+  $user_image = ($variables['api'] == 'rest') ? $tweet->user->profile_image_url : $tweet->profile_image_url;
+  $user_name = ($variables['api'] == 'rest') ? $tweet->user->screen_name : $tweet->from_user;
   $html = <<<EOHTML
 <div class="twitter_block tweet">
   <div class="twitter_block_user">
-  <img src="{$tweet['profile_image_url']}" alt="Twitter Avitar"/>
-    <a class="twitter_block profile_image" href="http://twitter.com/{$tweet['from_user']}">
-        <span class="twitter_block_user_name">@{$tweet['from_user']}</span>
-      </a>
-    </div>
-  <div class="tweet_text"><p class="tweet">{$tweet['text']}</p></div>
+    <a class="twitter_block profile_image" href="http://twitter.com/{$user_name}">
+      <img src="{$user_image}" alt="Twitter Avatar" />
+      <span class="twitter_block_user_name">@{$user_name}</span>
+    </a>
+  </div>
+  <div class="tweet_text"><p class="tweet">{$text}</p></div> 
 </div>
 EOHTML;
 
@@ -279,14 +299,15 @@ EOHTML;
 }
 
 /**
- * Returns themed html for a twitter block
+ * Returns themed html for a twitter block.
  */
-function theme_twitter_block($twitter_result, $variables = array() ) {
-  foreach ($twitter_result as $tweet) {
-    $tweets[] = theme('twitter_block_tweets', array('tweet' => $tweet));
+function theme_twitter_block($variables) {
+  $twitter_result = $variables['twitter_result'];
+  foreach($twitter_result as $tweet) {  
+    $tweets[] = theme('twitter_block_tweets', array('tweet' => $tweet, 'api' => $variables['api'])); 
   }
 
-  // Don't show an empty block
+  // Don't show an empty block.
   if (count($twitter_result) > 0) {
     $html = '<div id="twitter_block_results" class="twitter_block">';
     $html .= theme('item_list', array('items' => $tweets));
@@ -295,22 +316,25 @@ function theme_twitter_block($twitter_result, $variables = array() ) {
   }
 }
 
+/**
+ * Convert nested URLs, account names and hash tags into links.
+ */
 function twitter_block_linkify($status_text) {
-  // linkify URLs
+  // Linkify URLs.
   $status_text = preg_replace(
     '/(https?:\/\/\S+)/',
     '<a href="\1">\1</a>',
     $status_text
   );
 
-  // linkify twitter users
+  // Linkify twitter users.
   $status_text = preg_replace(
     '/(^|\s)@(\w+)/',
     '\1@<a href="http://twitter.com/\2">\2</a>',
     $status_text
   );
 
-  // linkify tags
+  // Linkify tags.
   $status_text = preg_replace(
     '/(^|\s)#([\wåäöÅÄÖ]+)/',
     '\1#<a href="http://search.twitter.com/search?q=%23\2">\2</a>',
