diff --git a/src/cs-S3Zip.Tests/S3ZipTests.cs b/src/cs-S3Zip.Tests/S3ZipTests.cs
index 76e07ddfcad991b45d4a06bf73348bb1ba0ae789..7984204697dcde2526b23d9e351987e1c9ad0f81 100644
--- a/src/cs-S3Zip.Tests/S3ZipTests.cs
+++ b/src/cs-S3Zip.Tests/S3ZipTests.cs
@@ -56,7 +56,7 @@ namespace coscine.cs_S3Zip.Tests
             var zipUtilities = new ZipUtilities(_s3MultipartStreamConfiguration);
             using (var s3MultipartDownloadStream = new S3MultipartDownloadStream(key, _s3MultipartStreamConfiguration))
             {
-                using (var archive = new ZipArchive(s3MultipartDownloadStream, ZipArchiveMode.Read, true))
+                using (var archive = new ZipArchive(s3MultipartDownloadStream, ZipArchiveMode.Read))
                 {
                     zipUtilities.UnzipToFolder(archive, @"c:\temp\test2\");
                 }
diff --git a/src/cs-S3Zip/S3MultipartDownloadStream.cs b/src/cs-S3Zip/S3MultipartDownloadStream.cs
index f09325977327fab192055371b343dddddd6b2cb5..2b134032f1ffd8a88bad8dcc65cc227b5e2171e9 100644
--- a/src/cs-S3Zip/S3MultipartDownloadStream.cs
+++ b/src/cs-S3Zip/S3MultipartDownloadStream.cs
@@ -17,7 +17,7 @@ namespace coscine.cs_S3Zip
 
         public override bool CanRead => true;
 
-        public override bool CanSeek => false;
+        public override bool CanSeek => true;
 
         public override bool CanWrite => false;
 
@@ -54,26 +54,15 @@ namespace coscine.cs_S3Zip
 
         }
 
-        private void DownloadCurrentPart()
-        {
-            if (Position < Length)
-            {
-                DownloadPart(_part);
-                _part++;
-            }
-        }
-
-        private void DownloadPart(int part)
+        private void DownloadRange(ByteRange range)
         {
-            _position += _internalStream.Position;
-
             using (var client = new AmazonS3Client(S3MultipartStreamConfiguration.AccessKey, S3MultipartStreamConfiguration.SecretKey, S3MultipartStreamConfiguration.AmazonS3Config))
             {
                 var request = new GetObjectRequest
                 {
                     BucketName = S3MultipartStreamConfiguration.BucketName,
                     Key = Key,
-                    ByteRange = new ByteRange(part * S3MultipartStreamConfiguration.ChunckSize, (part + 1) * S3MultipartStreamConfiguration.ChunckSize - 1)
+                    ByteRange = range
                 };
 
                 _internalStream.SetLength(0);
@@ -84,7 +73,22 @@ namespace coscine.cs_S3Zip
                 }
             }
 
-            _internalStream.Position = 0;            
+            _internalStream.Position = 0;
+        }
+
+        private void DownloadCurrentPart()
+        {
+            if (Position < Length)
+            {
+                DownloadPart(_part);
+                _part++;
+            }
+        }
+
+        private void DownloadPart(int part)
+        {
+            _position += _internalStream.Position;
+            DownloadRange(new ByteRange(part * S3MultipartStreamConfiguration.ChunckSize, (part + 1) * S3MultipartStreamConfiguration.ChunckSize - 1));
         }
 
         public override void Flush()
@@ -114,9 +118,67 @@ namespace coscine.cs_S3Zip
             return read;
         }
 
+
+        private ByteRange CalculateByteRange(long position)
+        { 
+            long leftPosition;
+            long rightPosition;
+
+            if (position - (S3MultipartStreamConfiguration.ChunckSize / 2) < 0
+            && position + (S3MultipartStreamConfiguration.ChunckSize / 2) + S3MultipartStreamConfiguration.ChunckSize % 2 - 1 >= Length)
+            {
+                // both to small
+                leftPosition = 0;
+                rightPosition = Length - 1;
+            }
+            else if (position - (S3MultipartStreamConfiguration.ChunckSize / 2) < 0)
+            {
+                // left to small
+                leftPosition = 0;
+                rightPosition = S3MultipartStreamConfiguration.ChunckSize - 1;
+            }
+            else if (position + (S3MultipartStreamConfiguration.ChunckSize / 2) + S3MultipartStreamConfiguration.ChunckSize % 2 - 1 >= Length)
+            {
+                // right to small
+                leftPosition = Length - S3MultipartStreamConfiguration.ChunckSize - 1;
+                rightPosition = Length - 1;
+            }
+            else
+            {
+                // fits perfectly
+                leftPosition = position - (S3MultipartStreamConfiguration.ChunckSize / 2);
+                rightPosition = position + (S3MultipartStreamConfiguration.ChunckSize / 2) + S3MultipartStreamConfiguration.ChunckSize % 2 - 1;
+            }
+
+            return new ByteRange(leftPosition, rightPosition);
+        }
+
+
         public override long Seek(long offset, SeekOrigin origin)
         {
-            throw new System.NotImplementedException();
+            switch (origin)
+            {
+                case SeekOrigin.Begin:
+                    DownloadRange(CalculateByteRange(offset));
+                    _position = offset;
+                    break;
+                case SeekOrigin.Current:
+                    if (Position + offset > _position + _internalStream.Length || Position + offset < _position)
+                    {
+                        DownloadRange(CalculateByteRange(Position + offset));
+                        _position = Position + offset;
+                    } else
+                    {
+                        _internalStream.Position += offset;
+                    }
+                    break;
+                case SeekOrigin.End:
+                    DownloadRange(CalculateByteRange(_length - 1 + offset));
+                    _position = _length - 1 + offset;
+                    break;
+            }
+
+            return Position;
         }
 
         public override void SetLength(long value)