diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 2cfc47c112..a628bd4814 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -7,6 +7,7 @@ All definitions files include a header with the author and editors, so at some p
* [accounting.js](http://josscrowcroft.github.io/accounting.js/) (by [Sergey Gerasimov](https://github.com/gerich-home))
* [Ace Cloud9 Editor](http://ace.ajax.org/) (by [Diullei Gomes](https://github.com/Diullei))
* [Add To Home Screen](http://cubiq.org/add-to-home-screen) (by [James Wilkins](http://www.codeplex.com/site/users/view/jamesnw))
+* [adm-zip](https://github.com/cthackers/adm-zip) (by [John Vilk](https://github.com/jvilk/))
* [AmCharts](http://www.amcharts.com/) (by [Covobonomo](https://github.com/covobonomo/))
* [AngularAgility](https://github.com/AngularAgility/AngularAgility) (by [Roland Zwaga](https://github.com/rolandzwaga))
* [AngularBootstrapLightbox](https://github.com/compact/angular-bootstrap-lightbox) (by [Roland Zwaga](https://github.com/rolandzwaga))
diff --git a/adm-zip/adm-zip-tests.ts b/adm-zip/adm-zip-tests.ts
new file mode 100644
index 0000000000..f8583ae617
--- /dev/null
+++ b/adm-zip/adm-zip-tests.ts
@@ -0,0 +1,33 @@
+///
+import AdmZip = require("adm-zip");
+
+
+// reading archives
+var zip = new AdmZip("./my_file.zip");
+var zipEntries = zip.getEntries(); // an array of ZipEntry records
+
+zipEntries.forEach(function (zipEntry) {
+ console.log(zipEntry.toString()); // outputs zip entries information
+ if (zipEntry.entryName == "my_file.txt") {
+ console.log(zipEntry.getData().toString('utf8'));
+ }
+});
+// outputs the content of some_folder/my_file.txt
+console.log(zip.readAsText("some_folder/my_file.txt"));
+// extracts the specified file to the specified location
+zip.extractEntryTo(/*entry name*/"some_folder/my_file.txt", /*target path*/"/home/me/tempfolder", /*overwrite*/true)
+// extracts everything
+zip.extractAllTo(/*target path*/"/home/me/zipcontent/", /*overwrite*/true);
+
+
+// creating archives
+var zip = new AdmZip();
+
+// add file directly
+zip.addFile("test.txt", new Buffer("inner content of the file"), "entry comment goes here");
+// add local file
+zip.addLocalFile("/home/me/some_picture.png");
+// get everything as a buffer
+var willSendthis = zip.toBuffer();
+// or write everything to disk
+zip.writeZip(/*target file name*/"/home/me/files.zip");
diff --git a/adm-zip/adm-zip.d.ts b/adm-zip/adm-zip.d.ts
new file mode 100644
index 0000000000..9f2eb7dfdb
--- /dev/null
+++ b/adm-zip/adm-zip.d.ts
@@ -0,0 +1,300 @@
+// Type definitions for adm-zip v0.4.4
+// Project: https://github.com/cthackers/adm-zip
+// Definitions by: John Vilk
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+///
+
+declare module AdmZip {
+ class ZipFile {
+ /**
+ * Create a new, empty archive.
+ */
+ constructor();
+ /**
+ * Read an existing archive.
+ */
+ constructor(fileName: string);
+ /**
+ * Extracts the given entry from the archive and returns the content as a
+ * Buffer object.
+ * @param entry String with the full path of the entry
+ * @return Buffer or Null in case of error
+ */
+ readFile(entry: string): Buffer;
+ /**
+ * Extracts the given entry from the archive and returns the content as a
+ * Buffer object.
+ * @param entry ZipEntry object
+ * @return Buffer or Null in case of error
+ */
+ readFile(entry: IZipEntry): Buffer;
+ /**
+ * Asynchronous readFile
+ * @param entry String with the full path of the entry
+ * @param callback Called with a Buffer or Null in case of error
+ */
+ readFileAsync(entry: string, callback: (data: Buffer, err: string) => any): void;
+ /**
+ * Asynchronous readFile
+ * @param entry ZipEntry object
+ * @param callback Called with a Buffer or Null in case of error
+ * @return Buffer or Null in case of error
+ */
+ readFileAsync(entry: IZipEntry, callback: (data: Buffer, err: string) => any): void;
+ /**
+ * Extracts the given entry from the archive and returns the content as
+ * plain text in the given encoding
+ * @param entry String with the full path of the entry
+ * @param encoding Optional. If no encoding is specified utf8 is used
+ * @return String
+ */
+ readAsText(fileName: string, encoding?: string): string;
+ /**
+ * Extracts the given entry from the archive and returns the content as
+ * plain text in the given encoding
+ * @param entry ZipEntry object
+ * @param encoding Optional. If no encoding is specified utf8 is used
+ * @return String
+ */
+ readAsText(fileName: IZipEntry, encoding?: string): string;
+ /**
+ * Asynchronous readAsText
+ * @param entry String with the full path of the entry
+ * @param callback Called with the resulting string.
+ * @param encoding Optional. If no encoding is specified utf8 is used
+ */
+ readAsTextAsync(fileName: string, callback: (data: string) => any, encoding?: string): void;
+ /**
+ * Asynchronous readAsText
+ * @param entry ZipEntry object
+ * @param callback Called with the resulting string.
+ * @param encoding Optional. If no encoding is specified utf8 is used
+ */
+ readAsTextAsync(fileName: IZipEntry, callback: (data: string) => any, encoding?: string): void;
+ /**
+ * Remove the entry from the file or the entry and all its nested directories
+ * and files if the given entry is a directory
+ * @param entry String with the full path of the entry
+ */
+ deleteFile(entry: string): void;
+ /**
+ * Remove the entry from the file or the entry and all its nested directories
+ * and files if the given entry is a directory
+ * @param entry A ZipEntry object.
+ */
+ deleteFile(entry: IZipEntry): void;
+ /**
+ * Adds a comment to the zip. The zip must be rewritten after
+ * adding the comment.
+ * @param comment Content of the comment.
+ */
+ addZipComment(comment: string): void;
+ /**
+ * Returns the zip comment
+ * @return The zip comment.
+ */
+ getZipComment(): string;
+ /**
+ * Adds a comment to a specified zipEntry. The zip must be rewritten after
+ * adding the comment.
+ * The comment cannot exceed 65535 characters in length.
+ * @param entry String with the full path of the entry
+ * @param comment The comment to add to the entry.
+ */
+ addZipEntryComment(entry: string, comment: string): void;
+ /**
+ * Adds a comment to a specified zipEntry. The zip must be rewritten after
+ * adding the comment.
+ * The comment cannot exceed 65535 characters in length.
+ * @param entry ZipEntry object.
+ * @param comment The comment to add to the entry.
+ */
+ addZipEntryComment(entry: IZipEntry, comment: string): void;
+ /**
+ * Returns the comment of the specified entry.
+ * @param entry String with the full path of the entry.
+ * @return String The comment of the specified entry.
+ */
+ getZipEntryComment(entry: string): string;
+ /**
+ * Returns the comment of the specified entry
+ * @param entry ZipEntry object.
+ * @return String The comment of the specified entry.
+ */
+ getZipEntryComment(entry: IZipEntry): string;
+ /**
+ * Updates the content of an existing entry inside the archive. The zip
+ * must be rewritten after updating the content
+ * @param entry String with the full path of the entry.
+ * @param content The entry's new contents.
+ */
+ updateFile(entry: string, content: Buffer): void;
+ /**
+ * Updates the content of an existing entry inside the archive. The zip
+ * must be rewritten after updating the content
+ * @param entry ZipEntry object.
+ * @param content The entry's new contents.
+ */
+ updateFile(entry: IZipEntry, content: Buffer): void;
+ /**
+ * Adds a file from the disk to the archive.
+ * @param localPath Path to a file on disk.
+ * @param zipPath Path to a directory in the archive. Defaults to the empty
+ * string.
+ */
+ addLocalFile(localPath: string, zipPath?: string): void;
+ /**
+ * Adds a local directory and all its nested files and directories to the
+ * archive.
+ * @param localPath Path to a folder on disk.
+ * @param zipPath Path to a folder in the archive. Defaults to an empty
+ * string.
+ */
+ addLocalFolder(localPath: string, zipPath?: string): void;
+ /**
+ * Allows you to create a entry (file or directory) in the zip file.
+ * If you want to create a directory the entryName must end in / and a null
+ * buffer should be provided.
+ * @param entryName Entry path
+ * @param content Content to add to the entry; must be a 0-length buffer
+ * for a directory.
+ * @param comment Comment to add to the entry.
+ * @param attr Attribute to add to the entry.
+ */
+ addFile(entryName: string, data: Buffer, comment?: string, attr?: number): void;
+ /**
+ * Returns an array of ZipEntry objects representing the files and folders
+ * inside the archive
+ */
+ getEntries(): IZipEntry[];
+ /**
+ * Returns a ZipEntry object representing the file or folder specified by
+ * ``name``.
+ * @param name Name of the file or folder to retrieve.
+ * @return ZipEntry The entry corresponding to the name.
+ */
+ getEntry(name: string): IZipEntry;
+ /**
+ * Extracts the given entry to the given targetPath.
+ * If the entry is a directory inside the archive, the entire directory and
+ * its subdirectories will be extracted.
+ * @param entry String with the full path of the entry
+ * @param targetPath Target folder where to write the file
+ * @param maintainEntryPath If maintainEntryPath is true and the entry is
+ * inside a folder, the entry folder will be created in targetPath as
+ * well. Default is TRUE
+ * @param overwrite If the file already exists at the target path, the file
+ * will be overwriten if this is true. Default is FALSE
+ *
+ * @return Boolean
+ */
+ extractEntryTo(entryPath: string, targetPath: string, maintainEntryPath?: boolean, overwrite?: boolean): boolean;
+ /**
+ * Extracts the given entry to the given targetPath.
+ * If the entry is a directory inside the archive, the entire directory and
+ * its subdirectories will be extracted.
+ * @param entry ZipEntry object
+ * @param targetPath Target folder where to write the file
+ * @param maintainEntryPath If maintainEntryPath is true and the entry is
+ * inside a folder, the entry folder will be created in targetPath as
+ * well. Default is TRUE
+ * @param overwrite If the file already exists at the target path, the file
+ * will be overwriten if this is true. Default is FALSE
+ * @return Boolean
+ */
+ extractEntryTo(entryPath: IZipEntry, targetPath: string, maintainEntryPath?: boolean, overwrite?: boolean): boolean;
+ /**
+ * Extracts the entire archive to the given location
+ * @param targetPath Target location
+ * @param overwrite If the file already exists at the target path, the file
+ * will be overwriten if this is true. Default is FALSE
+ */
+ extractAllTo(targetPath: string, overwrite?: boolean): void;
+ /**
+ * Writes the newly created zip file to disk at the specified location or
+ * if a zip was opened and no ``targetFileName`` is provided, it will
+ * overwrite the opened zip
+ * @param targetFileName
+ */
+ writeZip(targetPath?: string): void;
+ /**
+ * Returns the content of the entire zip file as a Buffer object
+ * @return Buffer
+ */
+ toBuffer(): Buffer;
+ }
+
+ /**
+ * The ZipEntry is more than a structure representing the entry inside the
+ * zip file. Beside the normal attributes and headers a entry can have, the
+ * class contains a reference to the part of the file where the compressed
+ * data resides and decompresses it when requested. It also compresses the
+ * data and creates the headers required to write in the zip file.
+ */
+ interface IZipEntry {
+ /**
+ * Represents the full name and path of the file
+ */
+ entryName: string;
+ rawEntryName: Buffer;
+ /**
+ * Extra data associated with this entry.
+ */
+ extra: Buffer;
+ /**
+ * Entry comment.
+ */
+ comment: string;
+ name: string;
+ /**
+ * Read-Only property that indicates the type of the entry.
+ */
+ isDirectory: boolean;
+ /**
+ * Get the header associated with this ZipEntry.
+ */
+ header: Buffer;
+ /**
+ * Retrieve the compressed data for this entry. Note that this may trigger
+ * compression if any properties were modified.
+ */
+ getCompressedData(): Buffer;
+ /**
+ * Asynchronously retrieve the compressed data for this entry. Note that
+ * this may trigger compression if any properties were modified.
+ */
+ getCompressedDataAsync(callback: (data: Buffer) => void): void;
+ /**
+ * Set the (uncompressed) data to be associated with this entry.
+ */
+ setData(value: string): void;
+ /**
+ * Set the (uncompressed) data to be associated with this entry.
+ */
+ setData(value: Buffer): void;
+ /**
+ * Get the decompressed data associated with this entry.
+ */
+ getData(): Buffer;
+ /**
+ * Asynchronously get the decompressed data associated with this entry.
+ */
+ getDataAsync(callback: (data: Buffer) => void): void;
+ /**
+ * Returns the CEN Entry Header to be written to the output zip file, plus
+ * the extra data and the entry comment.
+ */
+ packHeader(): Buffer;
+ /**
+ * Returns a nicely formatted string with the most important properties of
+ * the ZipEntry.
+ */
+ toString(): string;
+ }
+}
+
+declare module "adm-zip" {
+ import zipFile = AdmZip.ZipFile;
+ export = zipFile;
+}