“Zipper” A Zipping Component In .NET 3.5 Using C# 3.0

Recently I have posted a zipping plugin – “On the Fly Zip and Attach” – for Windows Live Writer. I actually developed this component that was consumed in the writer’s zipping plugin. I thought to share with you the approach of design/development of this component, from use cases to its implementation along with unit tests using Visual Studio-2008 Unit Test infrastructure.

The functionalities that we are looking for are pretty straight forward :-

  • The component shall Zip files and Directories
  • The component shall provides functionality to Unzip the files in some user specified directory.

These functionalities can be broken down into use cases, that leads/binds to the interface “IZipper”, shown in the diagram below:-

ZipperPrimaryUseCases

The outcome of the use cases is the interface for our Zipper component, here is the code for it in C# :-

    public interface IZipper
    {
        // Zipping use cases
        bool Zip();
        bool ZipAs(string zipFilePath);
        bool ZipAs(string zipFilePath, bool useRelativePath);
        void AddFile(string absoluteFilePath);
        void AddFiles(string[] files);
        void AddFolder(string absoluteFolderPath);
        bool Clear();

        // Unzipping use cases
        bool Unzip(string destFilesPath);
        string[] UnzipVirtual();
    }

In order to realize the interface/use cases, I planned to use .NET 3.5 frameworks “{System.IO.Packaging.ZipPackage}”. This is part of the larger framework “System.IO.Packaging” that was primarily developed by Microsoft for its document system, XPS (the basis for Open XML documents), you can read about its specification from Microsoft, here is the link “XML Paper Specification”. The assembly you need to reference for it is “ReachFramework.dll”.

Here is the static design or class diagram for it. “Zipper” class is the realization of “IZipper” interface. Zipper class uses a static “inner” class “ZipperHelper” that eventually uses the .NET Packaging System.

Zipper

Since the central role is of the class ZipperHelper, here is how it looks like -

/// <summary>
        /// Zipper helper, a generic zipping api/utility class
        /// </summary>
        public static class ZipperHelper
        {
            /// <summary>
            /// uses the external container to zip the file...
            /// </summary>
            /// <param name="zipFilePath"></param>
            /// <param name="filesPathList"></param>
            /// <param name="useRelativePath"></param>
            /// <returns></returns>
            public static bool ZipAs(string zipFilePath, List<string> filesPathList, bool useRelativePath)
            {
                bool isZippedOk = false;
                if (filesPathList.Count > 0)
                {
                    FileInfo fileInfo = new FileInfo(zipFilePath);

                    // <bad file check>, delete it, if it contains zero bytes...
                    if (fileInfo.Exists && (fileInfo.Length == 0))
                    {
                        fileInfo.Delete();
                    }

                    using (Package package = Package.Open(zipFilePath, FileMode.OpenOrCreate))
                    {
                        foreach (string filePath in filesPathList)
                        {
                            string fileCurrentPath = ZipperHelper.MakePathRelative(filePath, useRelativePath);

                            Uri uri = new Uri(fileCurrentPath, UriKind.Relative);
                            uri = PackUriHelper.CreatePartUri(uri);
                            if (package.PartExists(uri))
                            {
                                package.DeletePart(uri);
                            }

                            PackagePart part = package.CreatePart(uri, string.Empty, CompressionOption.Maximum);
                            using (Stream streamIn = new FileStream(filePath, FileMode.Open, FileAccess.Read))
                            using (Stream streamOut = part.GetStream())
                            {
                                Core.CopyStream(streamIn, streamOut);
                            }
                        }
                        isZippedOk = true;
                    }
                }
                return isZippedOk;
            }

            /// <summary>
            /// uses external zip file path and extracts files to the provided destination files path 
            /// </summary>
            /// <param name="zipFilePath"></param>
            /// <param name="destFilesPath"></param>
            /// <returns></returns>
            public static bool UnzipAs(string zipFilePath, string destFilesPath)
            {
                bool isUnZipOk = false;

                FileInfo fileInfo = new FileInfo(zipFilePath);
                if (fileInfo.Exists && (fileInfo.Length > 0))
                {
                    using (Package package = Package.Open(zipFilePath, FileMode.Open))
                    {
                        if (package.GetParts().Count() > 0)
                        {
                            foreach (PackagePart part in package.GetParts())
                            {
                                // combine the paths...
                                string filePath = Path.Combine(destFilesPath, ZipperHelper.GetNormalizedPath(part.Uri.OriginalString));

                                // if directory doesnt exist create it...
                                if (!Directory.Exists(Path.GetDirectoryName(filePath)))
                                {
                                    Directory.CreateDirectory(Path.GetDirectoryName(filePath));
                                }

                                using (Stream streamOut = new FileStream(filePath, FileMode.Create))
                                using (Stream streamIn = part.GetStream())
                                {
                                    Core.CopyStream(streamIn, streamOut);
                                }
                            }
                            isUnZipOk = true;
                        }
                    }
                }
                return isUnZipOk;
            }

            /// <summary>
            /// Get the internal list of a zip file.
            /// </summary>
            /// <param name="zipFilePath"></param>
            /// <returns>string[]</returns>
            public static string[] UnzipVirtual(string zipFilePath)
            {
                List<string> filesList = new List<string>();
                FileInfo fileInfo = new FileInfo(zipFilePath);
                if (fileInfo.Exists && (fileInfo.Length > 0))
                {
                    using (Package package = Package.Open(zipFilePath, FileMode.Open))
                    {
                        if (package.GetParts().Count() > 0)
                        {
                            foreach (PackagePart part in package.GetParts())
                            {
                                filesList.Add(ZipperHelper.GetProperPath(ZipperHelper.GetNormalizedPath(part.Uri.OriginalString)));
                            }
                        }
                    }
                }
                return filesList.ToArray();
            }

            private static string MakePathRelative(string filePath)
            {
                return MakePathRelative(filePath, true);
            }

            private static string MakePathRelative(string filePath, bool useRelativePath)
            {
                string fileCurrentPath = filePath;
                if (filePath.Contains(":"))
                {
                    if (useRelativePath)
                    {
                        // simple approach, the absolute path has a colon ":", so split it and get the next one... 
                        fileCurrentPath = filePath.Split(new char[] { ':' })[1];
                    }
                    else
                    {
                        fileCurrentPath = filePath.Replace(":", "_");
                    }
                }
                return fileCurrentPath;
            }

            // c_\windows\explorer.exe --> c:\windows\explorer.exe
            private static string GetProperPath(string filePath)
            {
                // work on a copy
                string fileCurrentPath = filePath;
                // tokenize the paths
                string[] filePaths = filePath.Split(new char[] { '\\' });
                // replace the first one that contains "_" with ":"
                filePaths[0] = filePaths[0].Replace("_", ":");
                // remove the first path from the original
                fileCurrentPath = fileCurrentPath.Remove(0, filePaths[0].Length);
                // now add the replaced token
                fileCurrentPath = filePaths[0] + fileCurrentPath;

                return fileCurrentPath.Replace("%20", " ").Replace("%5B", "[").Replace("%5D", "]");
            }

            private static string GetNormalizedPath(string filePath)
            {
                string path = filePath.Replace(@"/", @"\");
                if (path.StartsWith(@"\"))
                {
                    path = path.Remove(0, 1);
                }
                return path;
            }           
        }

There are three public methods, ZipAs(…), UnzipAs(…) and UnzipVirtual(…). If you look into the code, you have  noticed that we don't see any where the “System.IO.Packaging.ZipPackage”. Its actually created when you call the static method Open of the abstract Package class, i.e “Package.Open(zipFilePath, FileMode.Open))” Rest of the functionality is straight forward, Here is the sequence

  • Create the Package.
  • Package will be composed of Parts and those Parts represents the corresponding files.
  • While Zipping you Serialize them to File using the Core Utility Class’s CopyStream method.
  • In Case of Unzipping things will become reversed and You get the Parts using the package.GetParts(), method and then Serialize those files to output streams.

For its usage, I have included the Unit Tests, and here is the  class model for it.

ZipperTestProject

The Unit tests conforms to the IZipper interface/Use cases and the concrete implementation i.e Zipper object is created in the Factory method CreateIZipper(). Here is the usage code for the Unit Tests:-

/// <summary>
    ///This is a test class for IZipperTest and is intended
    ///to contain all IZipperTest Unit Tests
    ///</summary>
    [TestClass()]
    public class IZipperTest
    {
        private const string ZipFilePath = @"c:\shams\zipper\test.zip";
        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        #endregion

        /// <summary>
        /// Factory method.
        /// </summary>
        /// <returns></returns>
        internal virtual IZipper CreateIZipper()
        {
            // TODO: Instantiate an appropriate concrete class.
            IZipper target = new Shams.IO.ZippingPackage.Utils.Zipper(IZipperTest.ZipFilePath);
            return target;
        }

        /// <summary>
        ///A test for Zip
        ///</summary>
        [TestMethod()]
        public void ZipTest()
        {
            IZipper zipper = CreateIZipper();       // Initialize to an appropriate value
            zipper.AddFile(@"c:\windows\notepad.exe");
            zipper.AddFile(@"c:\windows\regedit.exe");
            zipper.AddFile(@"c:\windows\explorer.exe");
            zipper.AddFile(@"c:\windows\system32\winlogon.exe");

            bool expected = true;       // Initialize to an appropriate value
            bool actual = zipper.Zip();

            Assert.AreEqual(expected, actual);
            //Assert.Inconclusive("Verify the correctness of this test method.");
        }

        /// <summary>
        ///A test for ZipAs
        ///</summary>
        [TestMethod()]
        public void ZipAsTest()
        {
            IZipper zipper = CreateIZipper(); // TODO: Initialize to an appropriate value
            zipper.AddFile(@"c:\windows\notepad.exe");
            zipper.AddFile(@"c:\windows\regedit.exe");
            zipper.AddFile(@"c:\windows\explorer.exe");
            zipper.AddFile(@"c:\windows\system32\winlogon.exe");

            string zipFilePath = @"c:\shams\zipper\temp.zip";

            bool expected = true;
            bool actual = zipper.ZipAs(zipFilePath);

            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for ZipAs
        ///</summary>
        [TestMethod()]
        public void ZipAsTest1()
        {
            IZipper zipper = CreateIZipper(); // TODO: Initialize to an appropriate value
            zipper.AddFile(@"c:\windows\notepad.exe");
            zipper.AddFile(@"c:\windows\regedit.exe");
            zipper.AddFile(@"c:\windows\explorer.exe");
            zipper.AddFile(@"c:\windows\system32\winlogon.exe");

            string zipFilePath = @"c:\shams\zipper\temp.zip";

            // by default it is false, lets make it relative here.
            bool useRelativePath = true;

            bool expected = true;
            bool actual = zipper.ZipAs(zipFilePath, useRelativePath);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for UnZipVirtual
        ///</summary>
        [TestMethod()]
        public void UnzipVirtualTest()
        {
            IZipper zipper = CreateIZipper(); // TODO: Initialize to an appropriate value
            string[] expected = new string[] {@"c:\windows\explorer.exe",
                @"c:\windows\notepad.exe", 
                @"c:\windows\regedit.exe", 
                @"c:\windows\system32\winlogon.exe"};

            zipper.AddFiles(expected);
           
            string[] actual = zipper.UnzipVirtual();
            Assert.AreEqual(expected, actual);
            
            //Assert.Inconclusive("Verify the correctness of this test method.");
        }

         /// <summary>
        ///A test for UnZip
        ///</summary>
        [TestMethod()]
        public void UnzipTest()
        {
            IZipper zipper = CreateIZipper();
            string destFilesPath = @"c:\shams\zipper\temp1";
            bool expected = true;
            bool actual = zipper.Unzip(destFilesPath);
            Assert.AreEqual(expected, actual);
            //Assert.Inconclusive("Verify the correctness of this test method.");
        }

        /// <summary>
        ///A test for Clear
        ///</summary>
        [TestMethod()]
        public void ClearTest()
        {
            IZipper zipper = CreateIZipper(); // TODO: Initialize to an appropriate value
            string[] files = new string[] {@"c:\windows\notepad.exe", 
                @"c:\windows\regedit.exe", 
                @"c:\windows\explorer.exe", 
                @"c:\windows\system32\winlogon.exe"};

            zipper.AddFiles(files);
            bool expected = true; 
            bool actual = zipper.Clear();
            Assert.AreEqual(expected, actual);
            //Assert.Inconclusive("Verify the correctness of this test method.");
        }

        /// <summary>
        ///A test for AddFolder
        ///</summary>
        [TestMethod()]
        public void AddFolderTest()
        {
            IZipper zipper = CreateIZipper();
            string absoluteFolderPath = @"c:\shams\zipper";
            zipper.AddFolder(absoluteFolderPath);

            Assert.Inconclusive("A method that does not return a value cannot be verified.");
        }

        /// <summary>
        ///A test for AddFiles
        ///</summary>
        [TestMethod()]
        public void AddFilesTest()
        {
            IZipper zipper = CreateIZipper(); // TODO: Initialize to an appropriate value
            string[] files = new string[] {@"c:\windows\notepad.exe", 
                @"c:\windows\regedit.exe", 
                @"c:\windows\explorer.exe", 
                @"c:\windows\system32\winlogon.exe"};

            zipper.AddFiles(files);
            Assert.Inconclusive("A method that does not return a value cannot be verified.");
        }

        /// <summary>
        ///A test for AddFile
        ///</summary>
        [TestMethod()]
        public void AddFileTest()
        {
            IZipper zipper = CreateIZipper();
            string absoluteFilePath = @"c:\windows\explorer.exe";
            zipper.AddFile(absoluteFilePath);

            Assert.Inconclusive("A method that does not return a value cannot be verified.");
        }
    }

That's all for now, the source code and unit tests are all included in the attached project. Enjoy :)

 

Download File - Zipping-Package

 

If you enjoyed reading this blog, leave your valuable feedback and consider subscribing to the RSS feed. You can also subscribe to it by email. Also, you can follow me on Twitter. Thank you!
Technorati Tags: ,,,

Comments (3) -

used car parts ford taurus
12/8/2017 2:48:23 AM #

Excellent blog you've got here.. It?s difficult to find good quality writing like yours nowadays. I honestly appreciate individuals like you! Take care!!  Also visit my web blog  used car parts ford taurus - wallinside.com/...7spares-with-heavy-discount.html

enjoy working online
12/8/2017 9:59:00 PM #

Hi, I do think this is a great blog. I stumbledupon it ;) I may come back yet again since i have book marked it. Money and freedom is the greatest way to change, may you be rich and continue to help other people.  Also visit my web blog -  enjoy working online - https://steepster.com/bunnhegelund0

Consciência pagava a 1 ano antes em torno a $140,00.

Unecessary driving instead
12/9/2017 10:11:05 AM #

I am really impressed along with your writing abilities as neatly as with the structure in your weblog. Is this a paid theme or did you customize it yourself? Anyway stay up the nice high quality writing, it is rare to peer a nice blog like this one nowadays..  my site;  Unecessary driving instead - kincaid12grau.affiliatblogger.com/.../trucks-in-addition-to-their-truck-parts

go.xperian.ir
12/9/2017 5:52:59 PM #

No teu colo ele me levou inclusive seu quarto.

pld repair manual
12/10/2017 4:18:09 AM #

Good day! This is my first visit to your blog! We are a team of volunteers and starting a new project in a community in the same niche. Your blog provided us useful information to work on. You have done a wonderful job!

manage multiple vps
12/10/2017 6:31:04 PM #

web hosting cheap rate  best whm reseller hosting - www.buena.space/best-whm-reseller-hosting.html  is vps hosting faster than shared  web hosting providers in chennai - www.buena.space/...sting-providers-in-chennai.html  web server on mac mavericks  dedicated server price in chennai - www.buena.space/...ed-server-price-in-chennai.html  what does non dedicated server mean  dedicated server austria - www.buena.space/dedicated-server-austria.html  website hosting space  windows ssd vps - https://www.buena.space/windows-ssd-vps.html  shared server vs dedicated server in oracle  windows 7 dedicated server - www.buena.space/windows-7-dedicated-server.html  anti ddos dedicated servers  amsterdam dedicated server - www.buena.space/amsterdam-dedicated-server.html  best uk hosting for wordpress  web control panel open source - www.buena.space/web-control-panel-open-source.html  i7 4790 dedicated server  dedicated servers vs hosted servers - www.buena.space/...-servers-vs-hosted-servers.html  best reseller hosting provider in india  web hosting nz - https://www.buena.space/web-hosting-nz.html  cheapest australian windows vps  web hosting prices in pakistan - www.buena.space/...hosting-prices-in-pakistan.html  best cheap dedicated servers  email hosting services for small business - www.buena.space/...ervices-for-small-business.html  web hosting ranking by country  fastest wordpress hosting uk - www.buena.space/fastest-wordpress-hosting-uk.html  web hosting gold coast  cheap managed vps server - www.buena.space/cheap-managed-vps-server.html  vps cpanel license $10  wordpress premium hosting - www.buena.space/wordpress-premium-hosting.html  website hosting usa  rent dedicated server sweden - www.buena.space/rent-dedicated-server-sweden.html  website hosting malaysia  best hosts for wordpress sites - www.buena.space/...-hosts-for-wordpress-sites.html  cheap canadian dedicated servers  vps versus shared hosting - www.buena.space/vps-versus-shared-hosting.html  free  manage multiple vps - https://www.buena.space/manage-multiple-vps.html  server usa  cheapest vps server - https://www.buena.space/cheapest-vps-server.html  web hosting for wordpress sites  cheap vps reviews - https://www.buena.space/cheap-vps-reviews.html  top hosting reseller plans  what is the best hosting for wordpress - www.buena.space/...best-hosting-for-wordpress.html  vps windows server  web hosting nigeria - https://www.buena.space/web-hosting-nigeria.html  fast dedicated servers  vps or dedicated server - www.buena.space/vps-or-dedicated-server.html  windows vps 10gbps  virtual private hosting windows - www.buena.space/...al-private-hosting-windows.html  domain and hosting india  web hosting sites reviews ratings - www.buena.space/...ting-sites-reviews-ratings.html

unmanaged dedicated server hosting
12/10/2017 6:58:00 PM #

moving a wordpress site to another host  best wordpress hosting us - www.arnetta.space/best-wordpress-hosting-us.html  websites hosting for teachers  cpanel reseller hosting uk - www.arnetta.space/cpanel-reseller-hosting-uk.html  top 10 wordpress hosting services  web hosting vps windows - www.arnetta.space/web-hosting-vps-windows.html  uk dedicated servers reviews  cheap vps server hosting - www.arnetta.space/cheap-vps-server-hosting.html  vps ubuntu server 12.04  web hosting magento australia - www.arnetta.space/...osting-magento-australia.html  singapore reseller hosting  ssd vps definition - https://www.arnetta.space/ssd-vps-definition.html  free windows vps rdp  reseller email hosting - www.arnetta.space/reseller-email-hosting.html  managed windows vps  dedicated server unlimited bandwidth 1gbps - www.arnetta.space/...nlimited-bandwidth-1gbps.html  best hosting site for resellers  web hosting definitions - www.arnetta.space/web-hosting-definitions.html  dedicated server vs shared server in oracle  top 10 vps hosting india - www.arnetta.space/top-10-vps-hosting-india.html  move wordpress to different host  change wordpress host url - www.arnetta.space/change-wordpress-host-url.html  wordpress hosting monthly payment  dedicated server definition - www.arnetta.space/dedicated-server-definition.html   unmanaged dedicated server hosting - www.arnetta.space/...dedicated-server-hosting.html  server canada cheap  top 10 dedicated server providers - www.arnetta.space/...dicated-server-providers.html  web service hosting options  most affordable vps hosting - www.arnetta.space/most-affordable-vps-hosting.html  web hosting rates in india  web host sites review - www.arnetta.space/web-host-sites-review.html  the best wordpress hosting service  best vps hosting singapore - www.arnetta.space/best-vps-hosting-singapore.html  web hosting per month  hosting with wordpress - www.arnetta.space/hosting-with-wordpress.html  web hosting service providers in delhi  top 10 vps hosting india - www.arnetta.space/top-10-vps-hosting-india.html  best cheapest windows vps  web hosting ghana - https://www.arnetta.space/web-hosting-ghana.html  web hosting uk based  business class wordpress hosting - www.arnetta.space/...-class-wordpress-hosting.html  web hosting review forum  cheap vps server hosting india - www.arnetta.space/...vps-server-hosting-india.html  web hosting charges in kenya  anti ddos dedicated servers vps/vds - www.arnetta.space/...dedicated-servers-vpsvds.html  wordpress dedicated hosting  cheapest linux vps - https://www.arnetta.space/cheapest-linux-vps.html  australian vps server  buy vps windows 2008 - www.arnetta.space/buy-vps-windows-2008.html  windows vps rdp hosting  vps hosting australia review - www.arnetta.space/...hosting-australia-review.html

trial dedicated server
12/10/2017 7:05:05 PM #

australia vps server  cheap vps hosting unlimited bandwidth - www.albertha.club/...ting-unlimited-bandwidth.html  reseller hosting end user support  buy dedicated server hosting - www.albertha.club/...dedicated-server-hosting.html  cheap vps hosting germany  dedicated servers for sale - www.albertha.club/dedicated-servers-for-sale.html   trial dedicated server - www.albertha.club/trial-dedicated-server.html  server hosting ip  order vps server - https://www.albertha.club/order-vps-server.html  game server dedicated hosting  dedicated server hosting los angeles - www.albertha.club/...rver-hosting-los-angeles.html  vps server providers  best budget wordpress hosting - www.albertha.club/...budget-wordpress-hosting.html  cheap german windows vps  wordpress deploy shared hosting - www.albertha.club/...ss-deploy-shared-hosting.html  cheap domain hosting canada  buy vps linux - https://www.albertha.club/buy-vps-linux.html  private ssl on shared hosting  web hosting and domains for dummies - www.albertha.club/...-and-domains-for-dummies.html  website hosting australia cheap  australian wordpress hosting reviews - www.albertha.club/...ordpress-hosting-reviews.html  website hosting server space  web hosting thailand review - www.albertha.club/web-hosting-thailand-review.html  web hosting services in chennai  $1 windows vps trial - https://www.albertha.club/1-windows-vps-trial.html  web hosting reviews uk based  cheap windows 2003 vps - www.albertha.club/cheap-windows-2003-vps.html  cheapest vps with cpanel  web hosting in india - www.albertha.club/web-hosting-in-india.html  web hosting for beginners  dedicated magento hosting - www.albertha.club/dedicated-magento-hosting.html  web hosting philippines reviews  best domain hosting for wordpress - www.albertha.club/...in-hosting-for-wordpress.html  dedicated server with ati gpu  virtual dedicated server australia - www.albertha.club/...dicated-server-australia.html  web hosting austin tx  dual xeon dedicated server - www.albertha.club/dual-xeon-dedicated-server.html  1 dollar windows vps  web hosting blog cost - www.albertha.club/web-hosting-blog-cost.html  hosting shared ssl  dedicated server 2003 - www.albertha.club/dedicated-server-2003.html  wordpress hosting best  whm dedicated server - www.albertha.club/whm-dedicated-server.html  cpanel vps cheap  best canadian wordpress hosting - www.albertha.club/...nadian-wordpress-hosting.html  singapore vps server  dedicated rental server - www.albertha.club/dedicated-rental-server.html  share host  website design hosting and domain - www.albertha.club/...esign-hosting-and-domain.html  web design and hosting melbourne  web hosting unlimited storage - www.albertha.club/...osting-unlimited-storage.html

web hosting with email forwarding  web hosting sql server database - www.cassey.space/...sting-sql-server-database.html  dedicated server name server setup  website design and hosting uk - www.cassey.space/...ite-design-and-hosting-uk.html  web hosting aus  web hosts for photographers - www.cassey.space/web-hosts-for-photographers.html  best hosts for wordpress sites  cheap dedicated windows server - www.cassey.space/...-dedicated-windows-server.html  free ftp server hosting sites  cheap vps dedicated server - www.cassey.space/cheap-vps-dedicated-server.html  wordpress multi site managed hosting  master reseller hosting indonesia - www.cassey.space/...eseller-hosting-indonesia.html  free hosting php mysql phpmyadmin  podcast hosting wordpress - www.cassey.space/podcast-hosting-wordpress.html  vps server malaysia  free vps server windows 7 - www.cassey.space/free-vps-server-windows-7.html  web hosting with php and mysql support  wordpress host files for download - www.cassey.space/...s-host-files-for-download.html  using wordpress for video hosting  reseller hosting us - https://www.cassey.space/reseller-hosting-us.html  web hosting charges in india  web hosting cleveland ohio - www.cassey.space/web-hosting-cleveland-ohio.html  web mail bell hosting  dedicated server europe windows - www.cassey.space/...ted-server-europe-windows.html  website creation and hosting india  server dedicated low cost - www.cassey.space/server-dedicated-low-cost.html  singapore windows vps server  web hosting usa reviews - www.cassey.space/web-hosting-usa-reviews.html  vps hosting trial  dedicated hosting ip - https://www.cassey.space/dedicated-hosting-ip.html  cheap reseller hosting  domain name hosting nz - www.cassey.space/domain-name-hosting-nz.html  rent cheap vps server  web server on raspberry pi - www.cassey.space/web-server-on-raspberry-pi.html  advantages of dedicated server over shared hosting  move wordpress to another hosting site - www.cassey.space/...s-to-another-hosting-site.html  web hosting servers in india  how to host site in local iis - www.cassey.space/...to-host-site-in-local-iis.html  web server hosting cheap  photo hosting sites uk - www.cassey.space/photo-hosting-sites-uk.html  domain email hosting reviews uk  best hosting for wordpress uk - www.cassey.space/...-hosting-for-wordpress-uk.html   best virtual server hosting australia - www.cassey.space/...-server-hosting-australia.html  uk vps  cheapest vps germany - https://www.cassey.space/cheapest-vps-germany.html  very fast wordpress hosting  vps windows 5 usd - https://www.cassey.space/vps-windows-5-usd.html  move wordpress blog to hosting  web host provider - https://www.cassey.space/web-host-provider.html  web hosting for windows  dedicated server cheap usa - www.cassey.space/dedicated-server-cheap-usa.html

jeronimogoergen.com.br
12/11/2017 11:12:48 PM #

4 ed. Abundância a Janeiro: F. Alves, 1990.

linjawistud.com
12/12/2017 2:21:15 AM #

Howdy, i read your blog occasionally and i own a similar one and i was just wondering if you get a lot of spam comments? If so how do you protect against it, any plugin or anything you can suggest? I get so much lately it's driving me insane so any support is very much appreciated.  Feel free to surf to my webpage ...  linjawistud.com - linjawistud.com/.../242755

Add comment