Merge pull request #1633 from mfietz/improve_if_modified_since

Improve If-Modified-Since/ETag
diff --git a/app/src/androidTest/java/de/test/antennapod/handler/FeedHandlerTest.java b/app/src/androidTest/java/de/test/antennapod/handler/FeedHandlerTest.java
index 5836bb6..ee454ce 100644
--- a/app/src/androidTest/java/de/test/antennapod/handler/FeedHandlerTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/handler/FeedHandlerTest.java
@@ -162,7 +162,7 @@
         if (withImage) {
             image = new FeedImage(0, "image", null, "http://example.com/picture", false);
         }
-        Feed feed = new Feed(0, new Date(), "title", "http://example.com", "This is the description",
+        Feed feed = new Feed(0, null, "title", "http://example.com", "This is the description",
                 "http://example.com/payment", "Daniel", "en", null, "http://example.com/feed", image, file.getAbsolutePath(),
                 "http://example.com/feed", true);
         feed.setItems(new ArrayList<FeedItem>());
diff --git a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java
index d7a170c..7862e98 100644
--- a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java
@@ -115,7 +115,7 @@
 
     private Playable writeTestPlayable(String downloadUrl, String fileUrl) {
         final Context c = getInstrumentation().getTargetContext();
-        Feed f = new Feed(0, new Date(), "f", "l", "d", null, null, null, null, "i", null, null, "l", false);
+        Feed f = new Feed(0, null, "f", "l", "d", null, null, null, null, "i", null, null, "l", false);
         FeedPreferences prefs = new FeedPreferences(f.getId(), false, FeedPreferences.AutoDeleteAction.NO, null, null);
         f.setPreferences(prefs);
         f.setItems(new ArrayList<>());
diff --git a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java
index f06d2f2..5c3d329 100644
--- a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java
@@ -48,7 +48,7 @@
     private List<FeedItem> writeTestQueue(String pref) {
         final Context c = getInstrumentation().getTargetContext();
         final int NUM_ITEMS = 10;
-        Feed f = new Feed(0, new Date(), "title", "link", "d", null, null, null, null, "id", null, "null", "url", false);
+        Feed f = new Feed(0, null, "title", "link", "d", null, null, null, null, "id", null, "null", "url", false);
         f.setItems(new ArrayList<>());
         for (int i = 0; i < NUM_ITEMS; i++) {
             f.getItems().add(new FeedItem(0, pref + i, pref + i, "link", new Date(), FeedItem.PLAYED, f));
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBCleanupTests.java b/app/src/androidTest/java/de/test/antennapod/storage/DBCleanupTests.java
index afdaeea..7300df3 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBCleanupTests.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBCleanupTests.java
@@ -87,7 +87,7 @@
     public void testPerformAutoCleanupShouldDelete() throws IOException {
         final int NUM_ITEMS = EPISODE_CACHE_SIZE * 2;
 
-        Feed feed = new Feed("url", new Date(), "title");
+        Feed feed = new Feed("url", null, "title");
         List<FeedItem> items = new ArrayList<>();
         feed.setItems(items);
         List<File> files = new ArrayList<>();
@@ -143,7 +143,7 @@
     public void testPerformAutoCleanupHandleUnplayed() throws IOException {
         final int NUM_ITEMS = EPISODE_CACHE_SIZE * 2;
 
-        Feed feed = new Feed("url", new Date(), "title");
+        Feed feed = new Feed("url", null, "title");
         List<FeedItem> items = new ArrayList<FeedItem>();
         feed.setItems(items);
         List<File> files = new ArrayList<File>();
@@ -159,7 +159,7 @@
     public void testPerformAutoCleanupShouldNotDeleteBecauseInQueue() throws IOException {
         final int NUM_ITEMS = EPISODE_CACHE_SIZE * 2;
 
-        Feed feed = new Feed("url", new Date(), "title");
+        Feed feed = new Feed("url", null, "title");
         List<FeedItem> items = new ArrayList<>();
         feed.setItems(items);
         List<File> files = new ArrayList<>();
@@ -198,7 +198,7 @@
     public void testPerformAutoCleanupShouldNotDeleteBecauseFavorite() throws IOException {
         final int NUM_ITEMS = EPISODE_CACHE_SIZE * 2;
 
-        Feed feed = new Feed("url", new Date(), "title");
+        Feed feed = new Feed("url", null, "title");
         List<FeedItem> items = new ArrayList<>();
         feed.setItems(items);
         List<File> files = new ArrayList<>();
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBNullCleanupAlgorithmTest.java b/app/src/androidTest/java/de/test/antennapod/storage/DBNullCleanupAlgorithmTest.java
index 18a8d63..7205b42 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBNullCleanupAlgorithmTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBNullCleanupAlgorithmTest.java
@@ -82,7 +82,7 @@
     public void testPerformAutoCleanupShouldNotDelete() throws IOException {
         final int NUM_ITEMS = EPISODE_CACHE_SIZE * 2;
 
-        Feed feed = new Feed("url", new Date(), "title");
+        Feed feed = new Feed("url", null, "title");
         List<FeedItem> items = new ArrayList<>();
         feed.setItems(items);
         List<File> files = new ArrayList<>();
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBQueueCleanupAlgorithmTest.java b/app/src/androidTest/java/de/test/antennapod/storage/DBQueueCleanupAlgorithmTest.java
index 890897f..3bd508e 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBQueueCleanupAlgorithmTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBQueueCleanupAlgorithmTest.java
@@ -32,7 +32,7 @@
     public void testPerformAutoCleanupHandleUnplayed() throws IOException {
         final int NUM_ITEMS = EPISODE_CACHE_SIZE * 2;
 
-        Feed feed = new Feed("url", new Date(), "title");
+        Feed feed = new Feed("url", null, "title");
         List<FeedItem> items = new ArrayList<>();
         feed.setItems(items);
         List<File> files = new ArrayList<>();
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java b/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java
index 3988669..0fc3b18 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java
@@ -54,10 +54,10 @@
         PodDBAdapter adapter = PodDBAdapter.getInstance();
         adapter.open();
 
-        Feed feed1 = new Feed(0, new Date(), "A", "link", "d", null, null, null, "rss", "A", null, "", "", true);
-        Feed feed2 = new Feed(0, new Date(), "b", "link", "d", null, null, null, "rss", "b", null, "", "", true);
-        Feed feed3 = new Feed(0, new Date(), "C", "link", "d", null, null, null, "rss", "C", null, "", "", true);
-        Feed feed4 = new Feed(0, new Date(), "d", "link", "d", null, null, null, "rss", "d", null, "", "", true);
+        Feed feed1 = new Feed(0, null, "A", "link", "d", null, null, null, "rss", "A", null, "", "", true);
+        Feed feed2 = new Feed(0, null, "b", "link", "d", null, null, null, "rss", "b", null, "", "", true);
+        Feed feed3 = new Feed(0, null, "C", "link", "d", null, null, null, "rss", "C", null, "", "", true);
+        Feed feed4 = new Feed(0, null, "d", "link", "d", null, null, null, "rss", "d", null, "", "", true);
         adapter.setCompleteFeed(feed1);
         adapter.setCompleteFeed(feed2);
         adapter.setCompleteFeed(feed3);
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java b/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java
index 1894d65..5b2393d 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java
@@ -1,13 +1,9 @@
 package de.test.antennapod.storage;
 
 import android.content.Context;
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
 import android.test.FlakyTest;
 import android.test.InstrumentationTestCase;
 
-import java.io.File;
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
@@ -15,14 +11,11 @@
 
 import de.danoeh.antennapod.core.feed.Feed;
 import de.danoeh.antennapod.core.feed.FeedItem;
-import de.danoeh.antennapod.core.feed.FeedMedia;
 import de.danoeh.antennapod.core.preferences.UserPreferences;
 import de.danoeh.antennapod.core.storage.DBReader;
 import de.danoeh.antennapod.core.storage.DBTasks;
 import de.danoeh.antennapod.core.storage.PodDBAdapter;
 
-import static de.test.antennapod.storage.DBTestUtils.saveFeedlist;
-
 /**
  * Test class for DBTasks
  */
@@ -57,7 +50,7 @@
     public void testUpdateFeedNewFeed() {
         final int NUM_ITEMS = 10;
 
-        Feed feed = new Feed("url", new Date(), "title");
+        Feed feed = new Feed("url", null, "title");
         feed.setItems(new ArrayList<>());
         for (int i = 0; i < NUM_ITEMS; i++) {
             feed.getItems().add(new FeedItem(0, "item " + i, "id " + i, "link " + i, new Date(), FeedItem.UNPLAYED, feed));
@@ -75,8 +68,8 @@
     /** Two feeds with the same title, but different download URLs should be treated as different feeds. */
     public void testUpdateFeedSameTitle() {
 
-        Feed feed1 = new Feed("url1", new Date(), "title");
-        Feed feed2 = new Feed("url2", new Date(), "title");
+        Feed feed1 = new Feed("url1", null, "title");
+        Feed feed2 = new Feed("url2", null, "title");
 
         feed1.setItems(new ArrayList<>());
         feed2.setItems(new ArrayList<>());
@@ -91,7 +84,7 @@
         final int NUM_ITEMS_OLD = 10;
         final int NUM_ITEMS_NEW = 10;
 
-        final Feed feed = new Feed("url", new Date(), "title");
+        final Feed feed = new Feed("url", null, "title");
         feed.setItems(new ArrayList<>());
         for (int i = 0; i < NUM_ITEMS_OLD; i++) {
             feed.getItems().add(new FeedItem(0, "item " + i, "id " + i, "link " + i, new Date(i), FeedItem.PLAYED, feed));
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java b/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java
index 0af8afa..78b8077 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java
@@ -44,7 +44,7 @@
         PodDBAdapter adapter = PodDBAdapter.getInstance();
         adapter.open();
         for (int i = 0; i < numFeeds; i++) {
-            Feed f = new Feed(0, new Date(), "feed " + i, "link" + i, "descr", null, null,
+            Feed f = new Feed(0, null, "feed " + i, "link" + i, "descr", null, null,
                     null, null, "id" + i, null, null, "url" + i, false, new FlattrStatus(), false, null, null, false);
             f.setItems(new ArrayList<>());
             for (int j = 0; j < numItems; j++) {
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java b/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java
index eaae932..0e1d19f 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java
@@ -59,13 +59,14 @@
         adapter.close();
     }
 
-    public void testSetFeedMediaPlaybackInformation() throws IOException, ExecutionException, InterruptedException {
+    public void testSetFeedMediaPlaybackInformation()
+            throws IOException, ExecutionException, InterruptedException, TimeoutException {
         final int POSITION = 50;
         final long LAST_PLAYED_TIME = 1000;
         final int PLAYED_DURATION = 60;
         final int DURATION = 100;
 
-        Feed feed = new Feed("url", new Date(), "title");
+        Feed feed = new Feed("url", null, "title");
         List<FeedItem> items = new ArrayList<>();
         feed.setItems(items);
         FeedItem item = new FeedItem(0, "Item", "Item", "url", new Date(), FeedItem.PLAYED, feed);
@@ -73,13 +74,13 @@
         FeedMedia media = new FeedMedia(0, item, DURATION, 1, 1, "mime_type", "dummy path", "download_url", true, null, 0, 0);
         item.setMedia(media);
 
-        DBWriter.setFeedItem(item).get();
+        DBWriter.setFeedItem(item).get(TIMEOUT, TimeUnit.SECONDS);
 
         media.setPosition(POSITION);
         media.setLastPlayedTime(LAST_PLAYED_TIME);
         media.setPlayedDuration(PLAYED_DURATION);
 
-        DBWriter.setFeedMediaPlaybackInformation(item.getMedia()).get();
+        DBWriter.setFeedMediaPlaybackInformation(item.getMedia()).get(TIMEOUT, TimeUnit.SECONDS);
 
         FeedItem itemFromDb = DBReader.getFeedItem(item.getId());
         FeedMedia mediaFromDb = itemFromDb.getMedia();
@@ -90,12 +91,13 @@
         assertEquals(DURATION, mediaFromDb.getDuration());
     }
 
-    public void testDeleteFeedMediaOfItemFileExists() throws IOException, ExecutionException, InterruptedException {
+    public void testDeleteFeedMediaOfItemFileExists()
+            throws IOException, ExecutionException, InterruptedException, TimeoutException {
         File dest = new File(getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER), "testFile");
 
         assertTrue(dest.createNewFile());
 
-        Feed feed = new Feed("url", new Date(), "title");
+        Feed feed = new Feed("url", null, "title");
         List<FeedItem> items = new ArrayList<>();
         feed.setItems(items);
         FeedItem item = new FeedItem(0, "Item", "Item", "url", new Date(), FeedItem.PLAYED, feed);
@@ -112,7 +114,8 @@
         assertTrue(media.getId() != 0);
         assertTrue(item.getId() != 0);
 
-        DBWriter.deleteFeedMediaOfItem(getInstrumentation().getTargetContext(), media.getId()).get();
+        DBWriter.deleteFeedMediaOfItem(getInstrumentation().getTargetContext(), media.getId())
+                .get(TIMEOUT, TimeUnit.SECONDS);
         media = DBReader.getFeedMedia(media.getId());
         assertNotNull(media);
         assertFalse(dest.exists());
@@ -124,7 +127,7 @@
         File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
         assertNotNull(destFolder);
 
-        Feed feed = new Feed("url", new Date(), "title");
+        Feed feed = new Feed("url", null, "title");
         feed.setItems(new ArrayList<>());
 
         // create Feed image
@@ -197,7 +200,7 @@
         File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
         assertNotNull(destFolder);
 
-        Feed feed = new Feed("url", new Date(), "title");
+        Feed feed = new Feed("url", null, "title");
         feed.setItems(new ArrayList<>());
 
         feed.setImage(null);
@@ -253,7 +256,7 @@
         File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
         assertNotNull(destFolder);
 
-        Feed feed = new Feed("url", new Date(), "title");
+        Feed feed = new Feed("url", null, "title");
         feed.setItems(null);
 
         // create Feed image
@@ -290,7 +293,7 @@
         File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
         assertNotNull(destFolder);
 
-        Feed feed = new Feed("url", new Date(), "title");
+        Feed feed = new Feed("url", null, "title");
         feed.setItems(new ArrayList<>());
 
         // create Feed image
@@ -342,7 +345,7 @@
         File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
         assertNotNull(destFolder);
 
-        Feed feed = new Feed("url", new Date(), "title");
+        Feed feed = new Feed("url", null, "title");
         feed.setItems(new ArrayList<>());
 
         // create Feed image
@@ -400,7 +403,7 @@
         File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
         assertNotNull(destFolder);
 
-        Feed feed = new Feed("url", new Date(), "title");
+        Feed feed = new Feed("url", null, "title");
         feed.setItems(new ArrayList<>());
 
         // create Feed image
@@ -472,7 +475,7 @@
         File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
         assertNotNull(destFolder);
 
-        Feed feed = new Feed("url", new Date(), "title");
+        Feed feed = new Feed("url", null, "title");
         feed.setItems(new ArrayList<FeedItem>());
 
         // create Feed image
@@ -528,7 +531,7 @@
 
     private FeedMedia playbackHistorySetup(Date playbackCompletionDate) {
         final Context context = getInstrumentation().getTargetContext();
-        Feed feed = new Feed("url", new Date(), "title");
+        Feed feed = new Feed("url", null, "title");
         feed.setItems(new ArrayList<FeedItem>());
         FeedItem item = new FeedItem(0, "title", "id", "link", new Date(), FeedItem.PLAYED, feed);
         FeedMedia media = new FeedMedia(0, item, 10, 0, 1, "mime", null, "url", false, playbackCompletionDate, 0, 0);
@@ -542,9 +545,10 @@
         return media;
     }
 
-    public void testAddItemToPlaybackHistoryNotPlayedYet() throws ExecutionException, InterruptedException {
+    public void testAddItemToPlaybackHistoryNotPlayedYet()
+            throws ExecutionException, InterruptedException, TimeoutException {
         FeedMedia media = playbackHistorySetup(null);
-        DBWriter.addItemToPlaybackHistory(media).get();
+        DBWriter.addItemToPlaybackHistory(media).get(TIMEOUT, TimeUnit.SECONDS);
         PodDBAdapter adapter = PodDBAdapter.getInstance();
         adapter.open();
         media = DBReader.getFeedMedia(media.getId());
@@ -554,11 +558,12 @@
         assertNotNull(media.getPlaybackCompletionDate());
     }
 
-    public void testAddItemToPlaybackHistoryAlreadyPlayed() throws ExecutionException, InterruptedException {
+    public void testAddItemToPlaybackHistoryAlreadyPlayed()
+            throws ExecutionException, InterruptedException, TimeoutException {
         final long OLD_DATE = 0;
 
         FeedMedia media = playbackHistorySetup(new Date(OLD_DATE));
-        DBWriter.addItemToPlaybackHistory(media).get();
+        DBWriter.addItemToPlaybackHistory(media).get(TIMEOUT, TimeUnit.SECONDS);
         PodDBAdapter adapter = PodDBAdapter.getInstance();
         adapter.open();
         media = DBReader.getFeedMedia(media.getId());
@@ -571,7 +576,7 @@
 
     private Feed queueTestSetupMultipleItems(final int NUM_ITEMS) throws InterruptedException, ExecutionException, TimeoutException {
         final Context context = getInstrumentation().getTargetContext();
-        Feed feed = new Feed("url", new Date(), "title");
+        Feed feed = new Feed("url", null, "title");
         feed.setItems(new ArrayList<>());
         for (int i = 0; i < NUM_ITEMS; i++) {
             FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.PLAYED, feed);
@@ -598,7 +603,7 @@
 
     public void testAddQueueItemSingleItem() throws InterruptedException, ExecutionException, TimeoutException {
         final Context context = getInstrumentation().getTargetContext();
-        Feed feed = new Feed("url", new Date(), "title");
+        Feed feed = new Feed("url", null, "title");
         feed.setItems(new ArrayList<>());
         FeedItem item = new FeedItem(0, "title", "id", "link", new Date(), FeedItem.PLAYED, feed);
         feed.getItems().add(item);
@@ -622,7 +627,7 @@
 
     public void testAddQueueItemSingleItemAlreadyInQueue() throws InterruptedException, ExecutionException, TimeoutException {
         final Context context = getInstrumentation().getTargetContext();
-        Feed feed = new Feed("url", new Date(), "title");
+        Feed feed = new Feed("url", null, "title");
         feed.setItems(new ArrayList<>());
         FeedItem item = new FeedItem(0, "title", "id", "link", new Date(), FeedItem.PLAYED, feed);
         feed.getItems().add(item);
@@ -688,7 +693,7 @@
     public void testRemoveQueueItem() throws InterruptedException, ExecutionException, TimeoutException {
         final int NUM_ITEMS = 10;
         final Context context = getInstrumentation().getTargetContext();
-        Feed feed = new Feed("url", new Date(), "title");
+        Feed feed = new Feed("url", null, "title");
         feed.setItems(new ArrayList<>());
         for (int i = 0; i < NUM_ITEMS; i++) {
             FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.PLAYED, feed);
@@ -733,7 +738,7 @@
 
     public void testMoveQueueItem() throws InterruptedException, ExecutionException, TimeoutException {
         final int NUM_ITEMS = 10;
-        Feed feed = new Feed("url", new Date(), "title");
+        Feed feed = new Feed("url", null, "title");
         feed.setItems(new ArrayList<>());
         for (int i = 0; i < NUM_ITEMS; i++) {
             FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.PLAYED, feed);
@@ -779,7 +784,7 @@
 
     public void testMarkFeedRead() throws InterruptedException, ExecutionException, TimeoutException {
         final int NUM_ITEMS = 10;
-        Feed feed = new Feed("url", new Date(), "title");
+        Feed feed = new Feed("url", null, "title");
         feed.setItems(new ArrayList<FeedItem>());
         for (int i = 0; i < NUM_ITEMS; i++) {
             FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.UNPLAYED, feed);
@@ -805,7 +810,7 @@
 
     public void testMarkAllItemsReadSameFeed() throws InterruptedException, ExecutionException, TimeoutException {
         final int NUM_ITEMS = 10;
-        Feed feed = new Feed("url", new Date(), "title");
+        Feed feed = new Feed("url", null, "title");
         feed.setItems(new ArrayList<>());
         for (int i = 0; i < NUM_ITEMS; i++) {
             FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.UNPLAYED, feed);
diff --git a/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java b/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java
index 13abbb1..432d4a4 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java
@@ -143,7 +143,7 @@
         for (int i = 0; i < NUM_FEEDS; i++) {
             File bitmapFile = newBitmapFile("image" + i);
             FeedImage image = new FeedImage(0, "image " + i, null, hostFile(bitmapFile), false);
-            Feed feed = new Feed(0, new Date(), "Title " + i, "http://example.com/" + i, "Description of feed " + i,
+            Feed feed = new Feed(0, null, "Title " + i, "http://example.com/" + i, "Description of feed " + i,
                     "http://example.com/pay/feed" + i, "author " + i, "en", Feed.TYPE_RSS2, "feed" + i, image, null,
                     "http://example.com/feed/src/" + i, false);
             image.setOwner(feed);
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
index 8c2b7f8..c7426c0 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/OnlineFeedViewActivity.java
@@ -35,7 +35,6 @@
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
@@ -258,7 +257,7 @@
     private void startFeedDownload(String url, String username, String password) {
         Log.d(TAG, "Starting feed download");
         url = URLChecker.prepareURL(url);
-        feed = new Feed(url, new Date(0));
+        feed = new Feed(url, null);
         if (username != null && password != null) {
             feed.setPreferences(new FeedPreferences(0, false, FeedPreferences.AutoDeleteAction.GLOBAL, username, password));
         }
@@ -410,7 +409,7 @@
 
         subscribeButton.setOnClickListener(v -> {
             try {
-                Feed f = new Feed(selectedDownloadUrl, new Date(0), feed.getTitle());
+                Feed f = new Feed(selectedDownloadUrl, null, feed.getTitle());
                 f.setPreferences(feed.getPreferences());
                 this.feed = f;
 
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java
index 582538f..893c929 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/DownloadLogAdapter.java
@@ -13,8 +13,6 @@
 import com.joanzapata.iconify.Iconify;
 import com.joanzapata.iconify.widget.IconButton;
 
-import java.util.Date;
-
 import de.danoeh.antennapod.R;
 import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
 import de.danoeh.antennapod.core.feed.Feed;
@@ -123,9 +121,8 @@
 			if(holder.typeId == Feed.FEEDFILETYPE_FEED) {
 				Feed feed = DBReader.getFeed(holder.id);
 				if (feed != null) {
-					feed.setLastUpdate(new Date(0)); // force refresh
 					try {
-						DBTasks.refreshFeed(context, feed);
+						DBTasks.forceRefreshFeed(context, feed);
 					} catch (DownloadRequestException e) {
 						e.printStackTrace();
 					}
diff --git a/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlFeedQueuer.java b/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlFeedQueuer.java
index 00327bc..cc27b6c 100644
--- a/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlFeedQueuer.java
+++ b/app/src/main/java/de/danoeh/antennapod/asynctask/OpmlFeedQueuer.java
@@ -6,7 +6,6 @@
 import android.os.AsyncTask;
 
 import java.util.Arrays;
-import java.util.Date;
 
 import de.danoeh.antennapod.activity.OpmlImportHolder;
 import de.danoeh.antennapod.core.R;
@@ -47,7 +46,7 @@
 		for (int idx = 0; idx < selection.length; idx++) {
 			OpmlElement element = OpmlImportHolder.getReadElements().get(
 					selection[idx]);
-			Feed feed = new Feed(element.getXmlUrl(), new Date(0),
+			Feed feed = new Feed(element.getXmlUrl(), null,
 					element.getText());
 			try {
 				requester.downloadFeed(context.getApplicationContext(), feed);
diff --git a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java
index 830e9d4..38030f4 100644
--- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java
+++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java
@@ -63,10 +63,10 @@
                                                final Feed selectedFeed) throws DownloadRequestException {
         switch (item.getItemId()) {
             case R.id.refresh_item:
-                DBTasks.refreshFeed(context, selectedFeed);
+                DBTasks.forceRefreshFeed(context, selectedFeed);
                 break;
             case R.id.refresh_complete_item:
-                DBTasks.refreshCompleteFeed(context, selectedFeed);
+                DBTasks.forceRefreshCompleteFeed(context, selectedFeed);
                 break;
             case R.id.filter_items:
                 showFilterDialog(context, selectedFeed);
diff --git a/app/src/main/java/de/danoeh/antennapod/receiver/SPAReceiver.java b/app/src/main/java/de/danoeh/antennapod/receiver/SPAReceiver.java
index ef6330f..8201fe3 100644
--- a/app/src/main/java/de/danoeh/antennapod/receiver/SPAReceiver.java
+++ b/app/src/main/java/de/danoeh/antennapod/receiver/SPAReceiver.java
@@ -8,7 +8,6 @@
 import android.widget.Toast;
 
 import java.util.Arrays;
-import java.util.Date;
 
 import de.danoeh.antennapod.BuildConfig;
 import de.danoeh.antennapod.R;
@@ -35,7 +34,7 @@
                 if (feedUrls != null) {
                     if (BuildConfig.DEBUG) Log.d(TAG, "Received feeds list: " + Arrays.toString(feedUrls));
                     for (String url : feedUrls) {
-                        Feed f  = new Feed(url, new Date(0));
+                        Feed f  = new Feed(url, null);
                         try {
                             DownloadRequester.getInstance().downloadFeed(context, f);
                         } catch (DownloadRequestException e) {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/backup/OpmlBackupAgent.java b/core/src/main/java/de/danoeh/antennapod/core/backup/OpmlBackupAgent.java
index 5ea0ba9..690fbdf 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/backup/OpmlBackupAgent.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/backup/OpmlBackupAgent.java
@@ -156,10 +156,9 @@
                 ArrayList<OpmlElement> opmlElements = new OpmlReader().readDocument(reader);
                 mChecksum = digester == null ? null : digester.digest();
                 DownloadRequester downloader = DownloadRequester.getInstance();
-                Date lastUpdated = new Date();
 
                 for (OpmlElement opmlElem : opmlElements) {
-                    Feed feed = new Feed(opmlElem.getXmlUrl(), lastUpdated, opmlElem.getText());
+                    Feed feed = new Feed(opmlElem.getXmlUrl(), null, opmlElem.getText());
 
                     try {
                         downloader.downloadFeed(mContext, feed);
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java b/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java
index 4be788f..d2d7cbc 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java
@@ -44,10 +44,12 @@
     private String author;
     private FeedImage image;
     private List<FeedItem> items;
+
     /**
-     * Date of last refresh.
+     * String that identifies the last update (adopted from Last-Modified or ETag header)
      */
-    private Date lastUpdate;
+    private String lastUpdate;
+
     private FlattrStatus flattrStatus;
     private String paymentLink;
     /**
@@ -91,18 +93,14 @@
     /**
      * This constructor is used for restoring a feed from the database.
      */
-    public Feed(long id, Date lastUpdate, String title, String link, String description, String paymentLink,
+    public Feed(long id, String lastUpdate, String title, String link, String description, String paymentLink,
                 String author, String language, String type, String feedIdentifier, FeedImage image, String fileUrl,
                 String downloadUrl, boolean downloaded, FlattrStatus status, boolean paged, String nextPageLink,
                 String filter, boolean lastUpdateFailed) {
         super(fileUrl, downloadUrl, downloaded);
         this.id = id;
         this.title = title;
-        if (lastUpdate != null) {
-            this.lastUpdate = (Date) lastUpdate.clone();
-        } else {
-            this.lastUpdate = null;
-        }
+        this.lastUpdate = lastUpdate;
         this.link = link;
         this.description = description;
         this.paymentLink = paymentLink;
@@ -126,7 +124,7 @@
     /**
      * This constructor is used for test purposes and uses a default flattr status object.
      */
-    public Feed(long id, Date lastUpdate, String title, String link, String description, String paymentLink,
+    public Feed(long id, String lastUpdate, String title, String link, String description, String paymentLink,
                 String author, String language, String type, String feedIdentifier, FeedImage image, String fileUrl,
                 String downloadUrl, boolean downloaded) {
         this(id, lastUpdate, title, link, description, paymentLink, author, language, type, feedIdentifier, image,
@@ -138,7 +136,6 @@
      */
     public Feed() {
         super();
-        lastUpdate = new Date();
         this.flattrStatus = new FlattrStatus();
     }
 
@@ -146,9 +143,9 @@
      * This constructor is used for requesting a feed download (it must not be used for anything else!). It should NOT be
      * used if the title of the feed is already known.
      */
-    public Feed(String url, Date lastUpdate) {
+    public Feed(String url, String lastUpdate) {
         super(null, url, false);
-        this.lastUpdate = (lastUpdate != null) ? (Date) lastUpdate.clone() : null;
+        this.lastUpdate = lastUpdate;
         this.flattrStatus = new FlattrStatus();
     }
 
@@ -156,7 +153,7 @@
      * This constructor is used for requesting a feed download (it must not be used for anything else!). It should be
      * used if the title of the feed is already known.
      */
-    public Feed(String url, Date lastUpdate, String title) {
+    public Feed(String url, String lastUpdate, String title) {
         this(url, lastUpdate);
         this.title = title;
         this.flattrStatus = new FlattrStatus();
@@ -166,7 +163,7 @@
      * This constructor is used for requesting a feed download (it must not be used for anything else!). It should be
      * used if the title of the feed is already known.
      */
-    public Feed(String url, Date lastUpdate, String title, String username, String password) {
+    public Feed(String url, String lastUpdate, String title, String username, String password) {
         this(url, lastUpdate, title);
         preferences = new FeedPreferences(0, true, FeedPreferences.AutoDeleteAction.GLOBAL, username, password);
     }
@@ -191,11 +188,9 @@
         int indexHide = cursor.getColumnIndex(PodDBAdapter.KEY_HIDE);
         int indexLastUpdateFailed = cursor.getColumnIndex(PodDBAdapter.KEY_LAST_UPDATE_FAILED);
 
-        Date lastUpdate = new Date(cursor.getLong(indexLastUpdate));
-
         Feed feed = new Feed(
                 cursor.getLong(indexId),
-                lastUpdate,
+                cursor.getString(indexLastUpdate),
                 cursor.getString(indexTitle),
                 cursor.getString(indexLink),
                 cursor.getString(indexDescription),
@@ -430,12 +425,12 @@
         this.items = list;
     }
 
-    public Date getLastUpdate() {
-        return (lastUpdate != null) ? (Date) lastUpdate.clone() : null;
+    public String getLastUpdate() {
+        return lastUpdate;
     }
 
-    public void setLastUpdate(Date lastUpdate) {
-        this.lastUpdate = (lastUpdate != null) ? (Date) lastUpdate.clone() : null;
+    public void setLastUpdate(String lastModified) {
+        this.lastUpdate = lastModified;
     }
 
     public String getFeedIdentifier() {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java b/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java
index 0b90cef..e7ebff1 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java
@@ -175,7 +175,7 @@
         for (String downloadUrl : changes.getAdded()) {
             if (false == localSubscriptions.contains(downloadUrl) &&
                     false == localRemoved.contains(downloadUrl)) {
-                Feed feed = new Feed(downloadUrl, new Date(0));
+                Feed feed = new Feed(downloadUrl, null);
                 DownloadRequester.getInstance().downloadFeed(this, feed);
             }
         }
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadRequest.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadRequest.java
index bc3006e..7f40ea6 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadRequest.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadRequest.java
@@ -4,6 +4,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
 
 import de.danoeh.antennapod.core.feed.FeedFile;
 import de.danoeh.antennapod.core.util.URLChecker;
@@ -15,7 +16,7 @@
     private final String title;
     private String username;
     private String password;
-    private long ifModifiedSince;
+    private String lastModified;
     private boolean deleteOnFailure;
     private final long feedfileId;
     private final int feedfileType;
@@ -60,7 +61,7 @@
         this.feedfileType = builder.feedfileType;
         this.username = builder.username;
         this.password = builder.password;
-        this.ifModifiedSince = builder.ifModifiedSince;
+        this.lastModified = builder.lastModified;
         this.deleteOnFailure = builder.deleteOnFailure;
         this.arguments = (builder.arguments != null) ? builder.arguments : new Bundle();
     }
@@ -71,7 +72,7 @@
         title = in.readString();
         feedfileId = in.readLong();
         feedfileType = in.readInt();
-        ifModifiedSince = in.readLong();
+        lastModified = in.readString();
         deleteOnFailure = (in.readByte() > 0);
         arguments = in.readBundle();
         if (in.dataAvail() > 0) {
@@ -98,7 +99,7 @@
         dest.writeString(title);
         dest.writeLong(feedfileId);
         dest.writeInt(feedfileType);
-        dest.writeLong(ifModifiedSince);
+        dest.writeString(lastModified);
         dest.writeByte((deleteOnFailure) ? (byte) 1 : 0);
         dest.writeBundle(arguments);
         if (username != null) {
@@ -127,7 +128,7 @@
 
         DownloadRequest that = (DownloadRequest) o;
 
-        if (ifModifiedSince != that.ifModifiedSince) return false;
+        if (lastModified != that.lastModified) return false;
         if (deleteOnFailure != that.deleteOnFailure) return false;
         if (feedfileId != that.feedfileId) return false;
         if (feedfileType != that.feedfileType) return false;
@@ -143,7 +144,6 @@
         if (title != null ? !title.equals(that.title) : that.title != null) return false;
         if (username != null ? !username.equals(that.username) : that.username != null)
             return false;
-
         return true;
     }
 
@@ -154,7 +154,7 @@
         result = 31 * result + (title != null ? title.hashCode() : 0);
         result = 31 * result + (username != null ? username.hashCode() : 0);
         result = 31 * result + (password != null ? password.hashCode() : 0);
-        result = 31 * result + (int)ifModifiedSince;
+        result = 31 * result + (lastModified != null ? lastModified.hashCode() : 0);
         result = 31 * result + (deleteOnFailure ? 1 : 0);
         result = 31 * result + (int) (feedfileId ^ (feedfileId >>> 32));
         result = 31 * result + feedfileType;
@@ -234,13 +234,14 @@
         this.password = password;
     }
 
-    public DownloadRequest setIfModifiedSince(long time) {
-        this.ifModifiedSince = time;
+    public DownloadRequest setLastModified(@Nullable String lastModified) {
+        this.lastModified = lastModified;
         return this;
     }
 
-    public long getIfModifiedSince() {
-        return this.ifModifiedSince;
+    @Nullable
+    public String getLastModified() {
+        return lastModified;
     }
 
     public boolean isDeleteOnFailure() {
@@ -257,7 +258,7 @@
         private String title;
         private String username;
         private String password;
-        private long ifModifiedSince;
+        private String lastModified;
         private boolean deleteOnFailure = false;
         private long feedfileId;
         private int feedfileType;
@@ -276,8 +277,8 @@
             return this;
         }
 
-        public Builder ifModifiedSince(long time) {
-            this.ifModifiedSince = time;
+        public Builder lastModified(String lastModified) {
+            this.lastModified = lastModified;
             return this;
         }
 
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java
index d69228c..72fa1e1 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java
@@ -824,7 +824,7 @@
         }
 
         private Pair<DownloadRequest, FeedHandlerResult> parseFeed(DownloadRequest request) {
-            Feed feed = new Feed(request.getSource(), new Date());
+            Feed feed = new Feed(request.getSource(), request.getLastModified());
             feed.setFile_url(request.getDestination());
             feed.setId(request.getFeedfileId());
             feed.setDownloaded(true);
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java
index 0b9fba6..e3a1952 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java
@@ -8,7 +8,6 @@
 import com.squareup.okhttp.Request;
 import com.squareup.okhttp.Response;
 import com.squareup.okhttp.ResponseBody;
-import com.squareup.okhttp.internal.http.HttpDate;
 
 import org.apache.commons.io.IOUtils;
 
@@ -28,6 +27,7 @@
 import de.danoeh.antennapod.core.ClientConfig;
 import de.danoeh.antennapod.core.R;
 import de.danoeh.antennapod.core.feed.FeedImage;
+import de.danoeh.antennapod.core.util.DateUtils;
 import de.danoeh.antennapod.core.util.DownloadError;
 import de.danoeh.antennapod.core.util.StorageUtils;
 import de.danoeh.antennapod.core.util.URIUtil;
@@ -67,13 +67,19 @@
             final URI uri = URIUtil.getURIFromRequestUrl(request.getSource());
             Request.Builder httpReq = new Request.Builder().url(uri.toURL())
                     .header("User-Agent", ClientConfig.USER_AGENT);
-            if(request.getIfModifiedSince() > 0) {
-                long threeDaysAgo = System.currentTimeMillis() - 1000*60*60*24*3;
-                if(request.getIfModifiedSince() > threeDaysAgo) {
-                    Date date = new Date(request.getIfModifiedSince());
-                    String httpDate = HttpDate.format(date);
-                    Log.d(TAG, "addHeader(\"If-Modified-Since\", \"" + httpDate + "\")");
-                    httpReq.addHeader("If-Modified-Since", httpDate);
+            if(!TextUtils.isEmpty(request.getLastModified())) {
+                String lastModified = request.getLastModified();
+                Date lastModifiedDate = DateUtils.parse(lastModified);
+                if(lastModifiedDate != null) {
+                    long threeDaysAgo = System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 3;
+                    if (lastModifiedDate.getTime() > threeDaysAgo) {
+                        Log.d(TAG, "addHeader(\"If-Modified-Since\", \"" + lastModified + "\")");
+                        httpReq.addHeader("If-Modified-Since", lastModified);
+                    }
+                } else {
+                    String eTag = lastModified;
+                    Log.d(TAG, "addHeader(\"If-None-Match\", \"" + eTag + "\")");
+                    httpReq.addHeader("If-None-Match", eTag);
                 }
             }
 
@@ -235,6 +241,12 @@
                     onFail(DownloadError.ERROR_IO_ERROR, "Download completed, but nothing was read");
                     return;
                 }
+                String lastModified = response.header("Last-Modified");
+                if(lastModified != null) {
+                    request.setLastModified(lastModified);
+                } else {
+                    request.setLastModified(response.header("ETag"));
+                }
                 onSuccess();
             }
 
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java
index efc60bf..ed593bb 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java
@@ -224,7 +224,28 @@
      */
     public static void refreshCompleteFeed(final Context context, final Feed feed) {
         try {
-            refreshFeed(context, feed, true);
+            refreshFeed(context, feed, true, false);
+        } catch (DownloadRequestException e) {
+            e.printStackTrace();
+            DBWriter.addDownloadStatus(
+                    new DownloadStatus(feed, feed
+                            .getHumanReadableIdentifier(),
+                            DownloadError.ERROR_REQUEST_ERROR, false, e
+                            .getMessage()
+                    )
+            );
+        }
+    }
+
+    /**
+     * Downloads all pages of the given feed even if feed has not been modified since last refresh
+     *
+     * @param context Used for requesting the download.
+     * @param feed    The Feed object.
+     */
+    public static void forceRefreshCompleteFeed(final Context context, final Feed feed) {
+        try {
+            refreshFeed(context, feed, true, true);
         } catch (DownloadRequestException e) {
             e.printStackTrace();
             DBWriter.addDownloadStatus(
@@ -248,11 +269,11 @@
     public static void loadNextPageOfFeed(final Context context, Feed feed, boolean loadAllPages) throws DownloadRequestException {
         if (feed.isPaged() && feed.getNextPageLink() != null) {
             int pageNr = feed.getPageNr() + 1;
-            Feed nextFeed = new Feed(feed.getNextPageLink(), new Date(), feed.getTitle() + "(" + pageNr + ")");
+            Feed nextFeed = new Feed(feed.getNextPageLink(), null, feed.getTitle() + "(" + pageNr + ")");
             nextFeed.setPageNr(pageNr);
             nextFeed.setPaged(true);
             nextFeed.setId(feed.getId());
-            DownloadRequester.getInstance().downloadFeed(context, nextFeed, loadAllPages);
+            DownloadRequester.getInstance().downloadFeed(context, nextFeed, loadAllPages, false);
         } else {
             Log.e(TAG, "loadNextPageOfFeed: Feed was either not paged or contained no nextPageLink");
         }
@@ -268,12 +289,25 @@
     public static void refreshFeed(Context context, Feed feed)
             throws DownloadRequestException {
         Log.d(TAG, "refreshFeed(feed.id: " + feed.getId() +")");
-        refreshFeed(context, feed, false);
+        refreshFeed(context, feed, false, false);
     }
 
-    private static void refreshFeed(Context context, Feed feed, boolean loadAllPages) throws DownloadRequestException {
+    /**
+     * Refresh a specific feed even if feed has not been modified since last refresh
+     *
+     * @param context Used for requesting the download.
+     * @param feed    The Feed object.
+     */
+    public static void forceRefreshFeed(Context context, Feed feed)
+            throws DownloadRequestException {
+        Log.d(TAG, "refreshFeed(feed.id: " + feed.getId() +")");
+        refreshFeed(context, feed, false, true);
+    }
+
+    private static void refreshFeed(Context context, Feed feed, boolean loadAllPages, boolean force)
+            throws DownloadRequestException {
         Feed f;
-        Date lastUpdate = feed.hasLastUpdateFailed() ? new Date(0) : feed.getLastUpdate();
+        String lastUpdate = feed.hasLastUpdateFailed() ? null : feed.getLastUpdate();
         if (feed.getPreferences() == null) {
             f = new Feed(feed.getDownload_url(), lastUpdate, feed.getTitle());
         } else {
@@ -281,7 +315,7 @@
                     feed.getPreferences().getUsername(), feed.getPreferences().getPassword());
         }
         f.setId(feed.getId());
-        DownloadRequester.getInstance().downloadFeed(context, f, loadAllPages);
+        DownloadRequester.getInstance().downloadFeed(context, f, loadAllPages, force);
     }
 
     /**
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java
index 0dc1dad..22c9538 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java
@@ -88,7 +88,7 @@
 
     private void download(Context context, FeedFile item, FeedFile container, File dest,
                           boolean overwriteIfExists, String username, String password,
-                          long ifModifiedSince, boolean deleteOnFailure, Bundle arguments) {
+                          String lastModified, boolean deleteOnFailure, Bundle arguments) {
         final boolean partiallyDownloadedFileExists = item.getFile_url() != null;
         if (isDownloadingFile(item)) {
                 Log.e(TAG, "URL " + item.getDownload_url()
@@ -129,7 +129,7 @@
 
         DownloadRequest.Builder builder = new DownloadRequest.Builder(dest.toString(), item)
                 .withAuthentication(username, password)
-                .ifModifiedSince(ifModifiedSince)
+                .lastModified(lastModified)
                 .deleteOnFailure(deleteOnFailure)
                 .withArguments(arguments);
         DownloadRequest request = builder.build();
@@ -162,24 +162,25 @@
      * @param feed Feed to download
      * @param loadAllPages Set to true to download all pages
      */
-    public synchronized void downloadFeed(Context context, Feed feed, boolean loadAllPages)
+    public synchronized void downloadFeed(Context context, Feed feed, boolean loadAllPages,
+                                          boolean force)
             throws DownloadRequestException {
         if (feedFileValid(feed)) {
             String username = (feed.getPreferences() != null) ? feed.getPreferences().getUsername() : null;
             String password = (feed.getPreferences() != null) ? feed.getPreferences().getPassword() : null;
-            long ifModifiedSince = feed.isPaged() ? 0 : feed.getLastUpdate().getTime();
+            String lastModified = feed.isPaged() || force ? null : feed.getLastUpdate();
 
             Bundle args = new Bundle();
             args.putInt(REQUEST_ARG_PAGE_NR, feed.getPageNr());
             args.putBoolean(REQUEST_ARG_LOAD_ALL_PAGES, loadAllPages);
 
             download(context, feed, null, new File(getFeedfilePath(context),
-                    getFeedfileName(feed)), true, username, password, ifModifiedSince, true, args);
+                    getFeedfileName(feed)), true, username, password, lastModified, true, args);
         }
     }
 
     public synchronized void downloadFeed(Context context, Feed feed) throws DownloadRequestException {
-        downloadFeed(context, feed, false);
+        downloadFeed(context, feed, false, false);
     }
 
     public synchronized void downloadMedia(Context context, FeedMedia feedmedia)
@@ -204,7 +205,7 @@
                         getMediafilename(feedmedia));
             }
             download(context, feedmedia, feed,
-                    dest, false, username, password, 0, false, null);
+                    dest, false, username, password, null, false, null);
         }
     }
 
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java
index 85ff8fc..5b7f5f7 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java
@@ -368,7 +368,7 @@
         values.put(KEY_FILE_URL, feed.getFile_url());
         values.put(KEY_DOWNLOAD_URL, feed.getDownload_url());
         values.put(KEY_DOWNLOADED, feed.isDownloaded());
-        values.put(KEY_LASTUPDATE, feed.getLastUpdate().getTime());
+        values.put(KEY_LASTUPDATE, feed.getLastUpdate());
         values.put(KEY_TYPE, feed.getType());
         values.put(KEY_FEED_IDENTIFIER, feed.getFeedIdentifier());
 
@@ -1151,7 +1151,7 @@
      * The returned cursor uses the FEEDITEM_SEL_FI_SMALL selection.
      */
     public final Cursor getNewItemsCursor() {
-        String[] args = new String[] {
+        Object[] args = new String[] {
                 SEL_FI_SMALL_STR,
                 TABLE_NAME_FEED_ITEMS,
                 TABLE_NAME_FEEDS,
@@ -1512,7 +1512,7 @@
      */
     private static class PodDBHelper extends SQLiteOpenHelper {
 
-        private final static int VERSION = 1050003;
+        private final static int VERSION = 1050004;
 
         private Context context;
 
@@ -1756,7 +1756,6 @@
                 db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_PUBDATE);
                 db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_READ);
             }
-
             if (oldVersion < 1050003) {
                 // Migrates feed list filter data
 
@@ -1804,6 +1803,11 @@
                 db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
                         + " ADD COLUMN " + PodDBAdapter.KEY_KEEP_UPDATED + " INTEGER DEFAULT 1");
             }
+            if (oldVersion < 1050004) {
+                // prevent old timestamps to be misinterpreted as ETags
+                db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS
+                        +" SET " + PodDBAdapter.KEY_LASTUPDATE + "=NULL");
+            }
 
             EventBus.getDefault().post(ProgressEvent.end());
         }