Repository: kpcyrd/sn0int (language: rust)

Issue:
Update and install concurrently
When installing or updating we should try to update/install at least two modules at a time to speed things up.


Discussion / hints:

Fix patch:
diff --git a/Cargo.lock b/Cargo.lock
index 8a84cf3a..c02e40b1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -7,7 +7,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "aho-corasick"
-version = "0.7.4"
+version = "0.7.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -64,7 +64,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "backtrace"
-version = "0.3.33"
+version = "0.3.34"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -88,7 +88,7 @@ version = "0.9.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "safemem 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -112,7 +112,7 @@ dependencies = [
  "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -169,12 +169,12 @@ dependencies = [
  "hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "hyper-rustls 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "pledge 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustls 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustyline 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustyline 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -268,7 +268,7 @@ dependencies = [
  "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -286,12 +286,12 @@ dependencies = [
  "hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "hyper-rustls 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "ipconfig 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "resolv-conf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustls 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
  "trust-dns 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "webpki-roots 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -364,9 +364,9 @@ dependencies = [
  "cookie 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "publicsuffix 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "try_from 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -572,12 +572,12 @@ dependencies = [
 
 [[package]]
 name = "der-parser"
-version = "2.1.0"
+version = "3.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "nom 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "rusticata-macros 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rusticata-macros 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -668,16 +668,16 @@ dependencies = [
 
 [[package]]
 name = "dirs"
-version = "2.0.1"
+version = "2.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "dirs-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "dirs-sys"
-version = "0.3.3"
+version = "0.3.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -693,7 +693,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -744,8 +744,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -773,7 +773,7 @@ name = "error-chain"
 version = "0.12.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "backtrace 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.34 (registry+https://github.com/rust-lang/crates.io-index)",
  "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -782,7 +782,7 @@ name = "failure"
 version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "backtrace 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.34 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -930,10 +930,10 @@ dependencies = [
 
 [[package]]
 name = "getrandom"
-version = "0.1.6"
+version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -962,7 +962,7 @@ dependencies = [
  "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
  "http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -974,12 +974,12 @@ version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "pest 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "pest_derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1029,7 +1029,7 @@ name = "html5ever"
 version = "0.23.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "markup5ever 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1103,7 +1103,7 @@ dependencies = [
  "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1158,7 +1158,7 @@ dependencies = [
 
 [[package]]
 name = "image"
-version = "0.22.0"
+version = "0.22.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1221,7 +1221,7 @@ dependencies = [
  "socket2 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "widestring 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "winreg 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1229,7 +1229,7 @@ name = "ipnetwork"
 version = "0.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1285,15 +1285,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 name = "lazy_static"
 version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
 
 [[package]]
 name = "lazycell"
 version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "lexical-core"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "stackvector 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "static_assertions 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "libc"
 version = "0.2.60"
@@ -1301,11 +1310,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "libflate"
-version = "0.1.25"
+version = "0.1.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rle-decode-fast 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1367,12 +1375,12 @@ name = "log"
 version = "0.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "log"
-version = "0.4.7"
+version = "0.4.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1416,11 +1424,11 @@ name = "markup5ever"
 version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf_codegen 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "string_cache_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1437,9 +1445,9 @@ name = "maxminddb"
 version = "0.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1449,7 +1457,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1501,13 +1509,11 @@ dependencies = [
 
 [[package]]
 name = "mime_guess"
-version = "2.0.0-alpha.6"
+version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "phf_codegen 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicase 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1539,7 +1545,7 @@ dependencies = [
  "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1552,7 +1558,7 @@ version = "2.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1585,7 +1591,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl 0.10.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.9.48 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1634,9 +1640,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "nom"
-version = "4.2.3"
+version = "5.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
+ "lexical-core 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1665,8 +1672,8 @@ version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "image 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "image 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1752,8 +1759,8 @@ dependencies = [
  "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1761,7 +1768,7 @@ dependencies = [
 
 [[package]]
 name = "opaque-debug"
-version = "0.2.2"
+version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -1908,7 +1915,7 @@ dependencies = [
  "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1987,7 +1994,6 @@ version = "0.7.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2063,7 +2069,7 @@ dependencies = [
  "error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2090,7 +2096,7 @@ name = "r2d2"
 version = "0.8.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "scheduled-thread-pool 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -2139,7 +2145,7 @@ name = "rand"
 version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "getrandom 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2182,7 +2188,7 @@ name = "rand_core"
 version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "getrandom 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2297,23 +2303,19 @@ dependencies = [
 
 [[package]]
 name = "regex"
-version = "1.2.0"
+version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "aho-corasick 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex-syntax 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "regex-syntax"
-version = "0.6.10"
+version = "0.6.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "ucd-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
-]
 
 [[package]]
 name = "remove_dir_all"
@@ -2338,11 +2340,11 @@ dependencies = [
  "http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "hyper 0.12.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mime_guess 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2353,7 +2355,7 @@ dependencies = [
  "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "winreg 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2395,7 +2397,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "pear 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2428,10 +2430,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "handlebars 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "notify 4.0.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "rocket 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2442,8 +2444,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "rocket 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rocket_failure_errors 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2452,8 +2454,8 @@ name = "rocket_failure_errors"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2487,10 +2489,10 @@ dependencies = [
 
 [[package]]
 name = "rusticata-macros"
-version = "1.1.0"
+version = "2.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "nom 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2499,7 +2501,7 @@ version = "0.15.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "sct 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2508,12 +2510,12 @@ dependencies = [
 
 [[package]]
 name = "rustyline"
-version = "5.0.0"
+version = "5.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "dirs 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2529,7 +2531,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "safemem"
-version = "0.3.0"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -2621,7 +2623,7 @@ dependencies = [
  "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cssparser 0.25.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf_codegen 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2651,15 +2653,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "serde"
-version = "1.0.97"
+version = "1.0.98"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.97"
+version = "1.0.98"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2674,7 +2676,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2684,7 +2686,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2705,7 +2707,7 @@ dependencies = [
  "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2727,7 +2729,7 @@ dependencies = [
  "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2739,7 +2741,7 @@ dependencies = [
  "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2748,7 +2750,7 @@ version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2770,8 +2772,8 @@ dependencies = [
  "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
  "sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2799,23 +2801,23 @@ dependencies = [
  "crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "ctrlc 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "der-parser 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "der-parser 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "diesel 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "diesel_migrations 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "dirs 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "hlua-badtouch 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "image 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "image 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "ipnetwork 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "kamadak-exif 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "kuchiki 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libflate 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libflate 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
  "libsqlite3-sys 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "maxminddb 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "md-5 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2826,13 +2828,13 @@ dependencies = [
  "pledge 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "publicsuffix 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustls 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustyline 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustyline 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "separator 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2842,6 +2844,8 @@ dependencies = [
  "sloppy-rfc4880 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "sn0int-common 0.7.0",
  "structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
+ "strum 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "strum_macros 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "syscallz 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "tar 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2853,7 +2857,7 @@ dependencies = [
  "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "webpki 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "webpki-roots 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "x509-parser 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "x509-parser 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2862,10 +2866,10 @@ name = "sn0int-common"
 version = "0.7.0"
 dependencies = [
  "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "nom 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rocket_failure_errors 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2880,7 +2884,7 @@ dependencies = [
  "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "oauth2 2.0.0-beta.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "reqwest 0.9.19 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2888,8 +2892,8 @@ dependencies = [
  "rocket_contrib 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rocket_failure 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "sn0int-common 0.7.0",
  "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2916,11 +2920,25 @@ name = "stable_deref_trait"
 version = "1.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "stackvector"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "state"
 version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "static_assertions"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "string"
 version = "0.2.1"
@@ -2938,7 +2956,7 @@ dependencies = [
  "new_debug_unreachable 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
  "string_cache_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -3051,7 +3069,7 @@ version = "0.11.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "seccomp-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "strum 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "strum_macros 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3205,7 +3223,7 @@ dependencies = [
  "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
  "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3250,7 +3268,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -3261,7 +3279,7 @@ dependencies = [
  "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3313,7 +3331,7 @@ dependencies = [
  "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3338,7 +3356,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3354,7 +3372,7 @@ dependencies = [
  "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
  "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3367,7 +3385,7 @@ name = "toml"
 version = "0.4.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -3375,7 +3393,7 @@ name = "toml"
 version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -3394,7 +3412,7 @@ dependencies = [
  "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "radix_trie 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3414,7 +3432,7 @@ dependencies = [
  "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
  "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "socket2 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3455,11 +3473,6 @@ name = "ucd-trie"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "ucd-util"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
 [[package]]
 name = "unicase"
 version = "1.4.2"
@@ -3512,6 +3525,14 @@ name = "unicode-xid"
 version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "unreachable"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "untrusted"
 version = "0.6.2"
@@ -3540,11 +3561,6 @@ name = "utf-8"
 version = "0.7.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "utf8-ranges"
-version = "1.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
 [[package]]
 name = "utf8parse"
 version = "0.1.1"
@@ -3599,7 +3615,7 @@ version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -3685,7 +3701,7 @@ dependencies = [
 
 [[package]]
 name = "winreg"
-version = "0.6.1"
+version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3710,14 +3726,14 @@ dependencies = [
 
 [[package]]
 name = "x509-parser"
-version = "0.5.1"
+version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "der-parser 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "der-parser 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "nom 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "rusticata-macros 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rusticata-macros 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -3746,7 +3762,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [metadata]
 "checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c"
-"checksum aho-corasick 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "36b7aa1ccb7d7ea3f437cf025a2ab1c47cc6c1bc9fc84918ff449def12f5e282"
+"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d"
 "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
 "checksum approx 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08abcc3b4e9339e33a3d0a5ed15d84a687350c05689d825e0f6655eef9e76a94"
 "checksum argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3f67b0b6a86dae6e67ff4ca2b6201396074996379fba2b92ff649126f37cb392"
@@ -3754,7 +3770,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d73f9beda665eaa98ab9e4f7442bd4e7de6652587de55b2525e52e29c1b0ba"
 "checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90"
 "checksum autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "22130e92352b948e7e82a49cdb0aa94f2211761117f29e052dd397c1ac33542b"
-"checksum backtrace 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)" = "88fb679bc9af8fa639198790a77f52d345fe13656c08b43afa9424c206b731c6"
+"checksum backtrace 0.3.34 (registry+https://github.com/rust-lang/crates.io-index)" = "b5164d292487f037ece34ec0de2fcede2faa162f085dd96d2385ab81b12765ba"
 "checksum backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "82a830b4ef2d1124a711c71d263c5abdc710ef8e907bd508c88be475cebc422b"
 "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
 "checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643"
@@ -3807,7 +3823,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum data-encoding-macro 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1995a2e32b5306e4f49cf55ffcf4365a4dab2c7ca3a97163a4f099ec2fee3453"
 "checksum data-encoding-macro-internal 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "dd41a6f6a292f3d5be0cd1562bd6007652279d6afe3246f2722749e927338f7a"
 "checksum deflate 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)" = "707b6a7b384888a70c8d2e8650b3e60170dfc6a67bb4aa67b6dfca57af4bedb4"
-"checksum der-parser 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e2240eda75e81eeac4d7e2899f17a8469d877c5e7f694c7801720bb26a019b0"
+"checksum der-parser 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8a853d5b7e1b274dce7ccda5a8db3331ddd0a9069138d78fa3eea78b7ed7004"
 "checksum devise 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e04ba2d03c5fa0d954c061fc8c9c288badadffc272ebb87679a89846de3ed3"
 "checksum devise_codegen 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "066ceb7928ca93a9bedc6d0e612a8a0424048b0ab1f75971b203d01420c055d7"
 "checksum devise_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf41c59b22b5e3ec0ea55c7847e5f358d340f3a8d6d53a5cf4f1564967f96487"
@@ -3817,8 +3833,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum diesel_migrations 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3cde8413353dc7f5d72fa8ce0b99a560a359d2c5ef1e5817ca731cd9008f4c"
 "checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90"
 "checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
-"checksum dirs 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1c4ef5a8b902d393339e2a2c7fe573af92ce7e0ee5a3ff827b4c9ad7e07e4fa1"
-"checksum dirs-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "937756392ec77d1f2dd9dc3ac9d69867d109a2121479d72c364e42f4cab21e2d"
+"checksum dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3"
+"checksum dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b"
 "checksum dotenv 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0d0a1279c96732bc6800ce6337b6a614697b0e74ae058dc03c62ebeb78b4d86"
 "checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e"
 "checksum dtoa-short 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "59020b8513b76630c49d918c33db9f4c91638e7d3404a28084083b87e33f76f2"
@@ -3850,7 +3866,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
 "checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
 "checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
-"checksum getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e65cce4e5084b14874c4e7097f38cab54f47ee554f9194673456ea379dcc4c55"
+"checksum getrandom 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "34f33de6f0ae7c9cb5e574502a562e2b512799e32abb801cd1e79ad952b62b49"
 "checksum gif 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "86c2f2b597d6e05c86ee5947b2223bda468fe8dad3e88e2a6520869322aaf568"
 "checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
 "checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462"
@@ -3870,7 +3886,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum hyper-rustls 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "15b66d1bd4864ef036adf2363409caa3acd63ebb4725957b66e621c8a36631a3"
 "checksum hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f"
 "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
-"checksum image 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1acf4f4c11b418c989773b139c0ae88ae1a17948549b6b65f2e15421dedc813f"
+"checksum image 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)" = "663a975007e0b49903e2e8ac0db2c432c465855f2d65f17883ba1476e85f0b42"
 "checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d"
 "checksum inflate 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff"
 "checksum inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40b54539f3910d6f84fbf9a643efd6e3aa6e4f001426c0329576128255994718"
@@ -3887,8 +3903,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
 "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
 "checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
+"checksum lexical-core 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b0f90c979adde96d19eb10eb6431ba0c441e2f9e9bdff868b2f6f5114ff519"
 "checksum libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "d44e80633f007889c7eff624b709ab43c92d708caad982295768a7b13ca3b5eb"
-"checksum libflate 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "90c6f86f4b0caa347206f916f8b687b51d77c6ef8ff18d52dd007491fd580529"
+"checksum libflate 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "45c97cf62125b79dcac52d506acdc4799f21a198597806947fd5f40dc7b93412"
 "checksum libsqlite3-sys 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fd6457c70bbff456d9fe49deaba35ec47c3e598bf8d7950ff0575ceb7a8a6ad1"
 "checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe"
 "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83"
@@ -3896,7 +3913,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed946d4529956a20f2d63ebe1b69996d5a2137c91913fe3ebbeff957f5bca7ff"
 "checksum lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8912e782533a93a167888781b836336a6ca5da6175c05944c86cf28c31104dc"
 "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
-"checksum log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c275b6ad54070ac2d665eef9197db647b32239c9d244bfb6f041a766d00da5b3"
+"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
 "checksum lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c"
 "checksum lua52-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d451db153c94e455dc817d388f9674f6232425c28db3509e90251c55b8df2f94"
 "checksum lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084"
@@ -3912,7 +3929,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum migrations_macros 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1664412abf7db2b8a6d58be42a38b099780cc542b5b350383b805d88932833fe"
 "checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0"
 "checksum mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)" = "3e27ca21f40a310bd06d9031785f4801710d566c184a6e15bad4f1d9b65f9425"
-"checksum mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)" = "30de2e4613efcba1ec63d8133f344076952090c122992a903359be5a4f99c3ed"
+"checksum mime_guess 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1a0ed03949aef72dbdf3116a383d7b38b4768e6f960528cd6a6044aa9ed68599"
 "checksum miniz_oxide 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c061edee74a88eb35d876ce88b94d77a0448a201de111c244b70d047f5820516"
 "checksum miniz_oxide_c_api 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6c675792957b0d19933816c4e1d56663c341dd9bfa31cb2140ff2267c1d8ecf4"
 "checksum mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23"
@@ -3925,7 +3942,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum nibble_vec 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c8d77f3db4bce033f4d04db08079b2ef1c3d02b44e86f25d08886fafa7756ffa"
 "checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce"
 "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
-"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
+"checksum nom 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e9761d859320e381010a4f7f8ed425f2c924de33ad121ace447367c713ad561b"
 "checksum notify 4.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "3572d71f13ea8ed41867accd971fd564aa75934cf7a1fae03ddb8c74a8a49943"
 "checksum nude 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "40aacfe8497e3396233681bc5c422e81a430d7aff081a1b6b3dcc39394e1d517"
 "checksum num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "57450397855d951f1a41305e54851b1a7b8f5d2e349543a02a2effe25459f718"
@@ -3937,7 +3954,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
 "checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273"
 "checksum oauth2 2.0.0-beta.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74ba388129499452d6e2cea5976ad4d308ba55d5007e1eb2e466796e2f113239"
-"checksum opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "93f5bb2e8e8dec81642920ccff6b61f1eb94fa3020c5a325c9851ff604152409"
+"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
 "checksum opener 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "998c59e83d9474c01127a96e023b7a04bb061dd286bf8bb939d31dc8d31a7448"
 "checksum openssl 0.10.24 (registry+https://github.com/rust-lang/crates.io-index)" = "8152bb5a9b5b721538462336e3bef9a539f892715e5037fda0f984577311af15"
 "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
@@ -3996,8 +4013,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
 "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
 "checksum redox_users 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe5204c3a17e97dde73f285d49be585df59ed84b50a872baf416e73b62c3828"
-"checksum regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6b23da8dfd98a84bd7e08700190a5d9f7d2d38abd4369dd1dae651bc40bfd2cc"
-"checksum regex-syntax 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "cd5485bf1523a9ed51c4964273f22f63f24e31632adb5dad134f488f86a3875c"
+"checksum regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88c3d9193984285d544df4a30c23a4e62ead42edf70a4452ceb76dac1ce05c26"
+"checksum regex-syntax 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b143cceb2ca5e56d5671988ef8b15615733e7ee16cd348e064333b251b89343f"
 "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
 "checksum reqwest 0.9.19 (registry+https://github.com/rust-lang/crates.io-index)" = "1d0777154c2c3eb54f5c480db01de845652d941e47191277cc673634c3853939"
 "checksum resolv-conf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b263b4aa1b5de9ffc0054a2386f96992058bb6870aab516f8cdeb8a667d56dcb"
@@ -4012,11 +4029,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum rocket_http 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b1391457ee4e80b40d4b57fa5765c0f2836b20d73bcbee4e3f35d93cf3b80817"
 "checksum rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f4dccf6f4891ebcc0c39f9b6eb1a83b9bf5d747cb439ec6fba4f3b977038af"
 "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
-"checksum rusticata-macros 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fe8c976e50876cb3423699b190e799ff4c8a1a4f47dc33f4036dd056c077b7bb"
+"checksum rusticata-macros 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1a2fec406dbe9a6def54a66dadbfa387c7f60e903691b208160d5e9c4586dff9"
 "checksum rustls 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f271e3552cd835fa28c541c34a7e8fdd8cdff09d77fe4eb8f6c42e87a11b096e"
-"checksum rustyline 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67e12e40e0240de07f0dab4f4dd01bdb15d74dc977026d4ba91666c41c679ade"
+"checksum rustyline 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b7d4ca3c9586d2c1f742284f032e328313ea55f3f60a3b0a17e2ca1a2bf9ae22"
 "checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997"
-"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9"
+"checksum safemem 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e133ccc4f4d1cd4f89cc8a7ff618287d56dc7f638b8e38fc32c5fdcadc339dd5"
 "checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421"
 "checksum schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f6abf258d99c3c1c5c2131d99d064e94b7b3dd5f416483057f308fea253339"
 "checksum scheduled-thread-pool 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bd07742e081ff6c077f5f6b283f12f32b9e7cc765b316160d66289b74546fbb3"
@@ -4032,8 +4049,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
 "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
 "checksum separator 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f97841a747eef040fcd2e7b3b9a220a7205926e60488e673d9e4926d27772ce5"
-"checksum serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)" = "d46b3dfedb19360a74316866cef04687cd4d6a70df8e6a506c63512790769b72"
-"checksum serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)" = "c22a0820adfe2f257b098714323563dd06426502abbbce4f51b72ef544c5027f"
+"checksum serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)" = "7fe5626ac617da2f2d9c48af5515a21d5a480dbd151e01bb1c355e26a3e68113"
+"checksum serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)" = "01e69e1b8a631f245467ee275b8c757b818653c6d704cdbcaeb56b56767b529c"
 "checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704"
 "checksum serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "642dd69105886af2efd227f75a520ec9b44a820d65bc133a9131f7d229fd165a"
 "checksum servo_arc 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432"
@@ -4049,7 +4066,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum socket2 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)" = "df028e0e632c2a1823d920ad74895e7f9128e6438cbc4bc6fd1f180e644767b9"
 "checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55"
 "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
+"checksum stackvector 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1c4725650978235083241fab0fdc8e694c3de37821524e7534a1a9061d1068af"
 "checksum state 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7345c971d1ef21ffdbd103a75990a15eb03604fc8b8852ca8cb418ee1a099028"
+"checksum static_assertions 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b4f8de36da215253eb5f24020bfaa0646613b48bf7ebe36cdfa37c3b3b33b241"
 "checksum string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d"
 "checksum string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423"
 "checksum string_cache_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eea1eee654ef80933142157fdad9dd8bc43cf7c74e999e369263496f04ff4da"
@@ -4102,7 +4121,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887"
 "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
 "checksum ucd-trie 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8f00ed7be0c1ff1e24f46c3d2af4859f7e863672ba3a6e92e7cff702bf9f06c2"
-"checksum ucd-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa9b3b49edd3468c0e6565d85783f51af95212b6fa3986a5500954f00b460874"
 "checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33"
 "checksum unicase 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a84e5511b2a947f3ae965dcb29b13b7b1691b6e7332cf5dbc1744138d5acb7f6"
 "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
@@ -4111,11 +4129,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
 "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
 "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
+"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
 "checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f"
 "checksum unveil 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "774088f12a68c21aa5d0a9901a5087ad4dfc8e5515fd3557349e8defc980a0e5"
 "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
 "checksum utf-8 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "05e42f7c18b8f902290b009cde6d651262f956c98bc51bca4cd1d511c9cd85c7"
-"checksum utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9d50aa7650df78abf942826607c62468ce18d9019673d4a2ebe1865dbb96ffde"
 "checksum utf8parse 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8772a4ccbb4e89959023bc5b7cb8623a795caa7092d99f3aa9501b9484d4557d"
 "checksum uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a"
 "checksum vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "33dd455d0f96e90a75803cfeb7f948768c08d70a6de9a8d2362461935698bf95"
@@ -4136,10 +4154,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 "checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba"
 "checksum winconsole 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ef84b96d10db72dd980056666d7f1e7663ce93d82fa33b63e71c966f4cf5032"
-"checksum winreg 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73f1f3c6c4d3cab118551b96c476a2caab920701e28875b64a458f2ecb96ec9d"
+"checksum winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9"
 "checksum winutil 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7daf138b6b14196e3830a588acf1e86966c694d3e8fb026fb105b8b5dca07e6e"
 "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
-"checksum x509-parser 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f229e801140da8500deb67fcae308657b39577d04b80a57c9479964c54c094d"
+"checksum x509-parser 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b86b92815858495482b74dab17c0b2b2399f7582b6e7ca621b87aebf8fd00e9"
 "checksum xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c"
 "checksum xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "541b12c998c5b56aa2b4e6f18f03664eef9a4fd0a246a55594efae6cc2d964b5"
 "checksum yansi 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d60c3b48c9cdec42fb06b3b84b5b087405e1fa1c644a1af3930e4dfafe93de48"
diff --git a/Cargo.toml b/Cargo.toml
index 2eca6542..f8a4a0c6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -63,8 +63,8 @@ maxminddb = "0.13"
 tar = "0.4.17"
 libflate = "0.1.14"
 threadpool = "1.7"
-x509-parser = "0.5.0"
-der-parser = "2.0"
+x509-parser = "0.6.0"
+der-parser = "3.0"
 atty = "0.2"
 bufstream = "0.1.4"
 tokio = "0.1.14"
@@ -73,6 +73,8 @@ bytes = "0.4"
 xml-rs = "0.8"
 bytesize = "1.0"
 ipnetwork = "0.14"
+strum = "0.15"
+strum_macros = "0.15"
 
 digest = "0.8.0"
 bs58 = "0.2.2"
diff --git a/README.md b/README.md
index 13a0f823..f1a9016b 100644
--- a/README.md
+++ b/README.md
@@ -154,6 +154,7 @@ For everything else please have a look at the [detailed list][1].
   - [http_mksession](https://sn0int.readthedocs.io/en/latest/reference.html#http-mksession)
   - [http_request](https://sn0int.readthedocs.io/en/latest/reference.html#http-request)
   - [http_send](https://sn0int.readthedocs.io/en/latest/reference.html#http-send)
+  - [http_fetch](https://sn0int.readthedocs.io/en/latest/reference.html#http-fetch)
   - [http_fetch_json](https://sn0int.readthedocs.io/en/latest/reference.html#http-fetch-json)
   - [img_load](https://sn0int.readthedocs.io/en/latest/reference.html#img-load)
   - [img_exif](https://sn0int.readthedocs.io/en/latest/reference.html#img-exif)
diff --git a/docs/reference.rst b/docs/reference.rst
index f07d66b4..5851ed9a 100644
--- a/docs/reference.rst
+++ b/docs/reference.rst
@@ -144,7 +144,7 @@ ttl.
 .. code-block:: lua
 
     -- this link is valid for 2min
-    domain_id = db_add('network-device', {
+    domain_id = db_add_ttl('network-device', {
         network_id=1,
         device_id=13,
     }, 120)
@@ -405,11 +405,31 @@ the following keys:
     if last_err() then return end
     if resp['status'] ~= 200 then return 'http status error: ' .. resp['status'] end
 
+http_fetch
+----------
+
+This does an http_send_ and also automatically validate the status code.
+
+.. note::
+   You almost always want this when setting the ``into_blob`` option since this
+   function validates the status code *before* inserting the response body into
+   blob storage.
+
+.. code-block:: lua
+
+    -- short form
+    data = http_fetch(req)
+    if last_err() then return end
+
+    -- long form
+    resp = http_send(req)
+    if last_err() then return end
+    if resp['status'] ~= 200 then return 'http status error: ' .. resp['status'] end
+
 http_fetch_json
 ---------------
 
-This is a shorthand for http_send_, validating the status code and parsing the
-response body as json.
+Identical to http_fetch_ but also automatically parses the response body as json.
 
 .. code-block:: lua
 
diff --git a/modules/dev/dasoertliche-reverse.lua b/modules/dev/dasoertliche-reverse.lua
new file mode 100644
index 00000000..5e2d4136
--- /dev/null
+++ b/modules/dev/dasoertliche-reverse.lua
@@ -0,0 +1,32 @@
+-- Description: Run phonenumber reverse lookups on dasoertliche.de
+-- Version: 0.1.0
+-- License: GPL-3.0
+-- Source: phonenumbers
+
+function run(arg)
+    session = http_mksession()
+    req = http_request(session, 'GET', 'https://www.dasoertliche.de/Controller', {
+        query={
+            form_name='search_inv',
+            ph=arg['value'],
+        }
+    })
+    r = http_send(req)
+    if last_err() then return end
+    if r['status'] ~= 200 then return 'http error: ' .. r['status'] end
+
+    x = html_select(r['text'], '#entry_1 a')
+    if not x then
+        -- no results
+        return clear_err()
+    end
+
+    -- strip &nbsp;
+    m = regex_find('[^\\xa0]+', x['text'])
+
+    if m then
+        db_update('phonenumber', arg, {
+            caller_name=m[1],
+        })
+    end
+end
diff --git a/modules/dev/shodan-certs.lua b/modules/dev/shodan-certs.lua
new file mode 100644
index 00000000..b403ae19
--- /dev/null
+++ b/modules/dev/shodan-certs.lua
@@ -0,0 +1,53 @@
+-- Description: Find IPs using certificates for target subdomains
+-- Version: 0.1.0
+-- License: GPL-3.0
+-- Source: subdomains
+-- Keyring-Access: shodan
+
+function contains(list, search)
+    for i=1, #list do
+        if list[i] == search then
+            return true
+        end
+    end
+    return false
+end
+
+function run(arg)
+    local key = keyring('shodan')[1]
+    if not key then
+        return 'Missing required shodan access key'
+    end
+    local access_key = key['access_key']
+
+    local session = http_mksession()
+    local req = http_request(session, 'GET', 'https://api.shodan.io/shodan/host/search', {
+        query={
+            key=access_key,
+            query='ssl:' .. arg['value'],
+        }
+    })
+    local data = http_fetch_json(req)
+    if last_err() then return end
+
+    for i=1, #data['matches'] do
+        local host = data['matches'][i]
+        -- debug(host)
+
+        local crt = x509_parse_pem(host['ssl']['chain'][1])
+        if last_err() then return end
+
+        ipaddr_id = db_add('ipaddr', {
+            value=host['ip_str'],
+        })
+        if last_err() then return end
+
+        if contains(crt['valid_names'], arg['value']) then
+            db_add('subdomain-ipaddr', {
+                subdomain_id=arg['id'],
+                ip_addr_id=ipaddr_id,
+            })
+            if last_err() then return end
+        end
+    end
+end
diff --git a/modules/dev/telefonbuch-reverse.lua b/modules/dev/telefonbuch-reverse.lua
new file mode 100644
index 00000000..6f0dd78e
--- /dev/null
+++ b/modules/dev/telefonbuch-reverse.lua
@@ -0,0 +1,29 @@
+-- Description: Run phonenumber reverse lookups on dastelefonbuch.de
+-- Version: 0.1.0
+-- License: GPL-3.0
+-- Source: phonenumbers
+
+function run(arg)
+    session = http_mksession()
+
+    -- TODO: fix url encoding for +
+    query = arg['value']
+    query = query:gsub('+', '%%2B')
+    url = 'https://www.dastelefonbuch.de/R%C3%BCckw%C3%A4rts-Suche/' .. query
+
+    req = http_request(session, 'GET', url, {})
+    r = http_send(req)
+    if last_err() then return end
+
+    -- no data available
+    if r['status'] == 410 then return end
+    -- an error occured
+    if r['status'] ~= 200 then return 'http error: ' .. r['status'] end
+
+    x = html_select(r['text'], '#entry_1 div')
+    name = x['attrs']['title']
+
+    db_update('phonenumber', arg, {
+        caller_name=name,
+    })
+end
diff --git a/modules/harness/tux-img.lua b/modules/harness/tux-img.lua
index 8201cb0b..de82b7e9 100644
--- a/modules/harness/tux-img.lua
+++ b/modules/harness/tux-img.lua
@@ -8,11 +8,8 @@ function run()
     req = http_request(session, 'GET', 'https://www.kernel.org/theme/images/logos/tux.png', {
         into_blob=true,
     })
-    r = http_send(req)
+    r = http_fetch(req)
     if last_err() then return end
-    if r['status'] ~= 200 then
-        return 'http error: ' .. r['status']
-    end
 
     debug(r)
     db_add('image', {
diff --git a/sn0int-registry/sn0int-common/Cargo.toml b/sn0int-registry/sn0int-common/Cargo.toml
index 61fe79c9..cbaea420 100644
--- a/sn0int-registry/sn0int-common/Cargo.toml
+++ b/sn0int-registry/sn0int-common/Cargo.toml
@@ -13,4 +13,4 @@ serde_derive = "1.0"
 #rocket_failure_errors = { path = "../../../rocket_failure/rocket_failure_errors" }
 rocket_failure_errors = "0.2"
 failure = "0.1"
-nom = "4.0"
+nom = "5.0"
diff --git a/sn0int-registry/sn0int-common/src/api.rs b/sn0int-registry/sn0int-common/src/api.rs
index 9727f743..93d16713 100644
--- a/sn0int-registry/sn0int-common/src/api.rs
+++ b/sn0int-registry/sn0int-common/src/api.rs
@@ -31,6 +31,12 @@ pub struct ModuleInfoResponse {
     pub latest: Option<String>,
 }
 
+impl ModuleInfoResponse {
+    pub fn canonical(&self) -> String {
+        format!("{}/{}", self.author, self.name)
+    }
+}
+
 #[derive(Debug, Serialize, Deserialize)]
 pub struct SearchResponse {
     pub author: String,
diff --git a/sn0int-registry/sn0int-common/src/id.rs b/sn0int-registry/sn0int-common/src/id.rs
index 75617633..0ab9bdc3 100644
--- a/sn0int-registry/sn0int-common/src/id.rs
+++ b/sn0int-registry/sn0int-common/src/id.rs
@@ -1,38 +1,40 @@
 use crate::errors::*;
 use nom;
-use nom::types::CompleteStr;
 use serde::{de, Serialize, Serializer, Deserialize, Deserializer};
 use std::fmt;
 use std::result;
 use std::str::FromStr;
 
 
+#[inline(always)]
 fn valid_char(c: char) -> bool {
-    nom::is_alphanumeric(c as u8) || c == '-'
+    nom::character::is_alphanumeric(c as u8) || c == '-'
 }
 
 pub fn valid_name(name: &str) -> Result<()> {
-    if token(CompleteStr(name)).is_ok() {
+    if token(name).is_ok() {
         Ok(())
     } else {
         bail!("String contains invalid character")
     }
 }
 
-named!(module<CompleteStr, ModuleID>, do_parse!(
-    author: token   >>
-    tag!("/")       >>
-    name: token     >>
-    eof!()          >>
-    (
-        ModuleID {
-            author: author.to_string(),
-            name: name.to_string(),
-        }
-    )
-));
+fn module(s: &str) -> nom::IResult<&str, ModuleID> {
+    let (input, (author, _, name)) = nom::sequence::tuple((
+        token,
+        nom::bytes::complete::tag("/"),
+        token,
+    ))(s)?;
+    Ok((input, ModuleID {
+        author: author.to_string(),
+        name: name.to_string(),
+    }))
+}
 
-named!(token<CompleteStr, CompleteStr>, take_while1!(valid_char));
+#[inline]
+fn token(s: &str) -> nom::IResult<&str, &str> {
+    nom::bytes::complete::take_while1(valid_char)(s)
+}
 
 #[derive(Debug, PartialEq, Eq, Hash)]
 pub struct ModuleID {
@@ -50,8 +52,11 @@ impl FromStr for ModuleID {
     type Err = Error;
 
     fn from_str(s: &str) -> Result<ModuleID> {
-        let (_, module) = module(CompleteStr(s))
+        let (trailing, module) = module(s)
             .map_err(|err| format_err!("Failed to parse module id: {:?}", err))?;
+        if !trailing.is_empty() {
+            bail!("Trailing data in module id");
+        }
         Ok(module)
     }
 }
diff --git a/sn0int-registry/sn0int-common/src/metadata.rs b/sn0int-registry/sn0int-common/src/metadata.rs
index 3a8020b1..47163c56 100644
--- a/sn0int-registry/sn0int-common/src/metadata.rs
+++ b/sn0int-registry/sn0int-common/src/metadata.rs
@@ -3,7 +3,7 @@ use crate::errors::*;
 use std::str::FromStr;
 
 
-#[derive(Debug, PartialEq)]
+#[derive(Debug, PartialEq, Clone)]
 pub enum EntryType {
     Description,
     Version,
diff --git a/sn0int-registry/src/models.rs b/sn0int-registry/src/models.rs
index 0a311f67..04dd20db 100644
--- a/sn0int-registry/src/models.rs
+++ b/sn0int-registry/src/models.rs
@@ -221,7 +221,6 @@ impl Module {
             .left_join(releases::table)
             .group_by(modules::id)
             //.filter(q.matches(modules::search_vector))
-            .filter(modules::source.is_not_null())
             .order((
                 modules::featured.desc(),
                 diesel::dsl::sql::<BigInt>("sum").desc(),
@@ -240,12 +239,16 @@ impl Module {
                 featured,
                 source,
             };
-            if let Some(source) = &module.source {
-                if let Some(cat) = categories.get_mut(source) {
-                    cat.push(module);
-                } else {
-                    categories.insert(source.clone(), vec![module]);
-                }
+
+            let source = match &module.source {
+                Some(source) => source.as_str(),
+                _ => "none",
+            };
+
+            if let Some(cat) = categories.get_mut(source) {
+                cat.push(module);
+            } else {
+                categories.insert(source.to_string(), vec![module]);
             }
         }
 
diff --git a/sn0int-registry/src/routes/assets.rs b/sn0int-registry/src/routes/assets.rs
index 84cb6973..7a43c994 100644
--- a/sn0int-registry/src/routes/assets.rs
+++ b/sn0int-registry/src/routes/assets.rs
@@ -5,12 +5,27 @@ use crate::models::*;
 use rocket::http::{ContentType, Status};
 use rocket::http::hyper::header::{CacheControl, CacheDirective};
 use rocket_contrib::templates::Template;
+use std::cmp::Ordering;
 
 
 #[get("/")]
 pub fn index(connection: db::Connection) -> ApiResult<Template> {
-    let modules = Module::start_page(&connection)?;
     let asset_rev = ASSET_REV.as_str();
+
+    let mut modules = Module::start_page(&connection)?
+        .into_iter()
+        .map(|(k, v)| (k, v))
+        .collect::<Vec<_>>();
+
+    modules.sort_by(|a, b| {
+        match (a.0.as_str(), b.0.as_str()) {
+            ("none", "none") => Ordering::Equal,
+            ("none", _) => Ordering::Greater,
+            (_, "none") => Ordering::Less,
+            (a, b) => a.cmp(b),
+        }
+    });
+
     Ok(Template::render("index", json!({
         "ASSET_REV": asset_rev,
         "modules": modules,
diff --git a/sn0int-registry/templates/index.html.hbs b/sn0int-registry/templates/index.html.hbs
index 5a025eb1..240c68bc 100644
--- a/sn0int-registry/templates/index.html.hbs
+++ b/sn0int-registry/templates/index.html.hbs
@@ -22,9 +22,9 @@
         </code></p>
 
         {{#each modules}}
-            <h3>[ {{@key}} ]</h3>
+            <h3>[ {{this.0}} ]</h3>
             <ul class="modules">
-            {{#each this}}
+            {{#each this.1}}
                 <li>
                     <span class="mod-cell mod-name"><a href="#">{{this.author}}/{{this.name}}</a></span><span class="mod-cell mod-version">{{this.latest}}</span><span class="mod-cell mod-descr">{{this.description}}</span>
                 </li>
diff --git a/src/cmd/mod_cmd.rs b/src/cmd/mod_cmd.rs
index e5ba8602..588a23c9 100644
--- a/src/cmd/mod_cmd.rs
+++ b/src/cmd/mod_cmd.rs
@@ -1,18 +1,14 @@
 use crate::errors::*;
 
 use crate::args;
-use crate::args::Install;
-use crate::api::Client;
-use crate::config::Config;
-use colored::Colorize;
-use crate::engine::Module;
-use crate::registry;
+use crate::registry::{self, UpdateTask};
 use crate::shell::Readline;
 use crate::update::AutoUpdater;
+use crate::worker;
+use colored::Colorize;
+use std::fmt::Write;
 use structopt::StructOpt;
 use structopt::clap::AppSettings;
-use crate::term;
-use crate::worker;
 
 
 #[derive(Debug, StructOpt)]
@@ -47,6 +43,9 @@ pub struct List {
     /// Only show modules with a specific input source
     #[structopt(long="source")]
     pub source: Option<String>,
+    /// List outdated modules
+    #[structopt(long="outdated")]
+    pub outdated: bool,
 }
 
 #[derive(Debug, StructOpt)]
@@ -57,39 +56,14 @@ pub struct Reload {
 pub struct Update {
 }
 
-fn update(client: &Client, config: &Config, module: &Module) -> Result<()> {
-    let name = module.canonical();
-    let installed = module.version();
-
-    let label = format!("Searching for updates {}", name);
-    let infos = worker::spawn_fn(&label, || {
-        client.query_module(&module.id())
-    }, true)?;
-    debug!("Latest version: {:?}", infos);
-
-    let latest = infos.latest.ok_or_else(|| format_err!("Module doesn't have any released versions"))?;
-
-    if installed != latest {
-        let label = format!("Updating {}: {:?} -> {:?}", &name, installed, latest);
-        worker::spawn_fn(&label, || {
-            registry::run_install(&Install {
-                module: module.id(),
-                version: None,
-            }, &config)
-        }, true)?;
-
-        term::success(&format!("Updated {}: {:?} -> {:?}", &name, installed, latest));
-    }
-
-    Ok(())
-}
-
 pub fn run(rl: &mut Readline, args: &[String]) -> Result<()> {
     let args = Args::from_iter_safe(args)?;
     let config = rl.config().clone();
 
     match args.subcommand {
         SubCommand::List(list) => {
+            let autoupdate = AutoUpdater::load()?;
+
             for module in rl.engine().list() {
                 if let Some(source) = &list.source {
                     if !module.source_equals(&source) {
@@ -97,8 +71,17 @@ pub fn run(rl: &mut Readline, args: &[String]) -> Result<()> {
                     }
                 }
 
-                println!("{} ({})", module.canonical().green(),
-                                    module.version().yellow());
+                let canonical = module.canonical();
+
+                let mut out = String::new();
+                write!(&mut out, "{} ({})", canonical.green(),
+                                            module.version().yellow())?;
+                if autoupdate.is_outdated(&canonical) {
+                    write!(&mut out, " {}", "[outdated]".red())?;
+                } else if list.outdated {
+                    continue;
+                }
+                println!("{}", out);
                 println!("\t{}", module.description());
             }
         },
@@ -122,28 +105,27 @@ pub fn run(rl: &mut Readline, args: &[String]) -> Result<()> {
             }
         },
         SubCommand::Update(_) => {
-            let client = Client::new(&config)?;
+            let mut autoupdate = AutoUpdater::load()?;
 
-            let mut success = true;
+            let modules = rl.engine().list()
+                .into_iter()
+                .filter_map(|module| {
+                    let canonical = module.canonical();
 
-            for module in rl.engine().list() {
-                if module.is_private() {
-                    debug!("{} is a private module, skipping", module.canonical());
-                    continue;
-                }
+                    if module.is_private() {
+                        debug!("{} is a private module, skipping", canonical);
+                        return None;
+                    }
 
-                if let Err(err) = update(&client, &config, &module) {
-                    term::error(&format!("Failed to update {}: {}", module.canonical(), err));
-                    success = false;
-                }
-            }
+                    Some(UpdateTask::new(module.clone(), config.clone()))
+                })
+                .collect::<Vec<_>>();
 
-            // TODO: keep a list of outdated packages and remove them after they've been updated
-            if success {
-                let mut autoupdate = AutoUpdater::load()?;
-                autoupdate.all_updated();
-                autoupdate.save()?;
-            }
+            worker::spawn_multi(modules, |name| {
+                autoupdate.updated(&name);
+            }, 3)?;
+
+            autoupdate.save()?;
 
             // trigger reload
             run(rl, &[String::from("mod"), String::from("reload")])?;
diff --git a/src/cmd/quickstart_cmd.rs b/src/cmd/quickstart_cmd.rs
index 25d2b5ff..e8c1acb6 100644
--- a/src/cmd/quickstart_cmd.rs
+++ b/src/cmd/quickstart_cmd.rs
@@ -3,8 +3,10 @@ use crate::errors::*;
 use crate::args::Install;
 use crate::api::Client;
 use crate::cmd::mod_cmd;
-use crate::registry;
+use crate::registry::InstallTask;
 use crate::shell::Readline;
+use crate::update::AutoUpdater;
+use crate::worker;
 use structopt::StructOpt;
 use structopt::clap::AppSettings;
 use sn0int_common::ModuleID;
@@ -21,17 +23,26 @@ pub fn run(rl: &mut Readline, args: &[String]) -> Result<()> {
     let config = rl.config().clone();
 
     let client = Client::new(&config)?;
-
-    for module in client.quickstart()? {
-        info!("Installing {:?}", module);
-        registry::run_install(&Install {
-            module: ModuleID {
-                author: module.author,
-                name: module.name,
-            },
-            version: None,
-        }, &config)?;
-    }
+    let mut autoupdate = AutoUpdater::load()?;
+
+    let modules = client.quickstart()?
+        .into_iter()
+        .map(|module| {
+            InstallTask::new(Install {
+                module: ModuleID {
+                    author: module.author,
+                    name: module.name,
+                },
+                version: None,
+            }, config.clone())
+        })
+        .collect::<Vec<_>>();
+
+    worker::spawn_multi(modules, |name| {
+        autoupdate.updated(&name);
+    }, 3)?;
+
+    autoupdate.save()?;
 
     // trigger reload
     mod_cmd::run(rl, &[String::from("mod"), String::from("reload")])?;
diff --git a/src/db/mod.rs b/src/db/mod.rs
index 81801813..44842471 100644
--- a/src/db/mod.rs
+++ b/src/db/mod.rs
@@ -5,10 +5,10 @@ use diesel::expression::SqlLiteral;
 use diesel::expression::sql_literal::sql;
 use diesel::sql_types::Bool;
 use diesel::prelude::*;
+use strum_macros::{EnumString, IntoStaticStr};
 use crate::autonoscope::{RuleSet, RuleType};
 use crate::models::*;
 use crate::schema::*;
-use std::str::FromStr;
 use crate::migrations;
 use crate::worker;
 use crate::workspaces::Workspace;
@@ -33,14 +33,16 @@ impl DbChange {
 }
 
 #[derive(Debug, Serialize, Deserialize)]
+#[derive(EnumString, IntoStaticStr)]
+#[strum(serialize_all = "kebab_case")]
 pub enum Family {
     Domain,
     Subdomain,
-    IpAddr,
-    SubdomainIpAddr,
+    Ipaddr,
+    SubdomainIpaddr,
     Url,
     Email,
-    PhoneNumber,
+    Phonenumber,
     Device,
     Network,
     NetworkDevice,
@@ -52,29 +54,38 @@ pub enum Family {
     Netblock,
 }
 
-impl FromStr for Family {
-    type Err = Error;
-
-    fn from_str(s: &str) -> Result<Family> {
-        Ok(match s {
-            "domain" => Family::Domain,
-            "subdomain" => Family::Subdomain,
-            "ipaddr" => Family::IpAddr,
-            "subdomain-ipaddr" => Family::SubdomainIpAddr,
-            "url" => Family::Url,
-            "email" => Family::Email,
-            "phonenumber" => Family::PhoneNumber,
-            "device" => Family::Device,
-            "network" => Family::Network,
-            "network-device" => Family::NetworkDevice,
-            "account" => Family::Account,
-            "breach" => Family::Breach,
-            "breach-email" => Family::BreachEmail,
-            "image" => Family::Image,
-            "port" => Family::Port,
-            "netblock" => Family::Netblock,
-            _ => bail!("Unknown object family"),
-        })
+impl Family {
+    #[inline(always)]
+    pub fn as_str(&self) -> &'static str {
+        self.into()
+    }
+}
+
+#[derive(EnumString, IntoStaticStr)]
+#[strum(serialize_all = "snake_case")]
+pub enum Table {
+    Domains,
+    Subdomains,
+    Ipaddrs,
+    SubdomainIpaddrs,
+    Urls,
+    Emails,
+    Phonenumbers,
+    Devices,
+    Networks,
+    NetworkDevices,
+    Accounts,
+    Breaches,
+    BreachEmails,
+    Images,
+    Ports,
+    Netblocks,
+}
+
+impl Table {
+    #[inline(always)]
+    pub fn as_str(&self) -> &'static str {
+        self.into()
     }
 }
 
@@ -375,11 +386,11 @@ impl Database {
         match family {
             Family::Domain => self.get_opt_typed::<Domain>(&value),
             Family::Subdomain => self.get_opt_typed::<Subdomain>(&value),
-            Family::IpAddr => self.get_opt_typed::<IpAddr>(&value),
-            Family::SubdomainIpAddr => bail!("Unsupported operation"),
+            Family::Ipaddr => self.get_opt_typed::<IpAddr>(&value),
+            Family::SubdomainIpaddr => bail!("Unsupported operation"),
             Family::Url => self.get_opt_typed::<Url>(&value),
             Family::Email => self.get_opt_typed::<Email>(&value),
-            Family::PhoneNumber => self.get_opt_typed::<PhoneNumber>(&value),
+            Family::Phonenumber => self.get_opt_typed::<PhoneNumber>(&value),
             Family::Device => self.get_opt_typed::<Device>(&value),
             Family::Network => self.get_opt_typed::<Network>(&value),
             Family::NetworkDevice => bail!("Unsupported operation"),
@@ -634,4 +645,45 @@ mod tests {
                                     ]).unwrap();
         assert_eq!(filter, Filter::new(" value <= '123'"));
     }
+
+    #[test]
+    fn test_family_names() {
+        assert_eq!(Family::Domain.as_str(),             "domain");
+        assert_eq!(Family::Subdomain.as_str(),          "subdomain");
+        assert_eq!(Family::Ipaddr.as_str(),             "ipaddr");
+        assert_eq!(Family::SubdomainIpaddr.as_str(),    "subdomain-ipaddr");
+        assert_eq!(Family::Url.as_str(),                "url");
+        assert_eq!(Family::Email.as_str(),              "email");
+        assert_eq!(Family::Phonenumber.as_str(),        "phonenumber");
+        assert_eq!(Family::Device.as_str(),             "device");
+        assert_eq!(Family::Network.as_str(),            "network");
+        assert_eq!(Family::NetworkDevice.as_str(),      "network-device");
+        assert_eq!(Family::Account.as_str(),            "account");
+        assert_eq!(Family::Breach.as_str(),             "breach");
+        assert_eq!(Family::BreachEmail.as_str(),        "breach-email");
+        assert_eq!(Family::Image.as_str(),              "image");
+        assert_eq!(Family::Port.as_str(),               "port");
+        assert_eq!(Family::Netblock.as_str(),           "netblock");
+    }
+
+    #[test]
+    fn test_table_names() {
+        use super::Table;
+        assert_eq!(Table::Domains.as_str(),             "domains");
+        assert_eq!(Table::Subdomains.as_str(),          "subdomains");
+        assert_eq!(Table::Ipaddrs.as_str(),             "ipaddrs");
+        assert_eq!(Table::SubdomainIpaddrs.as_str(),    "subdomain_ipaddrs");
+        assert_eq!(Table::Urls.as_str(),                "urls");
+        assert_eq!(Table::Emails.as_str(),              "emails");
+        assert_eq!(Table::Phonenumbers.as_str(),        "phonenumbers");
+        assert_eq!(Table::Devices.as_str(),             "devices");
+        assert_eq!(Table::Networks.as_str(),            "networks");
+        assert_eq!(Table::NetworkDevices.as_str(),      "network_devices");
+        assert_eq!(Table::Accounts.as_str(),            "accounts");
+        assert_eq!(Table::Breaches.as_str(),            "breaches");
+        assert_eq!(Table::BreachEmails.as_str(),        "breach_emails");
+        assert_eq!(Table::Images.as_str(),              "images");
+        assert_eq!(Table::Ports.as_str(),               "ports");
+        assert_eq!(Table::Netblocks.as_str(),           "netblocks");
+    }
 }
diff --git a/src/db/ttl.rs b/src/db/ttl.rs
index c73c9f38..f02b10b1 100644
--- a/src/db/ttl.rs
+++ b/src/db/ttl.rs
@@ -1,5 +1,5 @@
 use crate::errors::*;
-use crate::db::Database;
+use crate::db::{Database, Table};
 use crate::schema::*;
 use crate::models::*;
 use chrono::{NaiveDateTime, Duration, Utc};
@@ -99,24 +99,24 @@ impl Ttl {
     }
 
     pub fn delete(&self, db: &Database) -> Result<()> {
-        match self.family.as_str() {
-            "domains" => Domain::delete_id(db, self.key)?,
-            "subdomains" => Subdomain::delete_id(db, self.key)?,
-            "ipaddrs" => IpAddr::delete_id(db, self.key)?,
-            "subdomain_ipaddrs" => SubdomainIpAddr::delete_id(db, self.key)?,
-            "urls" => Url::delete_id(db, self.key)?,
-            "emails" => Email::delete_id(db, self.key)?,
-            "phonenumbers" => PhoneNumber::delete_id(db, self.key)?,
-            "devices" => Device::delete_id(db, self.key)?,
-            "networks" => Network::delete_id(db, self.key)?,
-            "network_devices" => NetworkDevice::delete_id(db, self.key)?,
-            "accounts" => Account::delete_id(db, self.key)?,
-            "breaches" => Breach::delete_id(db, self.key)?,
-            "breach_emails" => BreachEmail::delete_id(db, self.key)?,
-            "images" => Image::delete_id(db, self.key)?,
-            "ports" => Port::delete_id(db, self.key)?,
-            "netblocks" => Netblock::delete_id(db, self.key)?,
-            _ => bail!("Unknown table"),
+        let family = self.family.parse::<Table>()?;
+        match family {
+            Table::Domains => Domain::delete_id(db, self.key)?,
+            Table::Subdomains => Subdomain::delete_id(db, self.key)?,
+            Table::Ipaddrs => IpAddr::delete_id(db, self.key)?,
+            Table::SubdomainIpaddrs => SubdomainIpAddr::delete_id(db, self.key)?,
+            Table::Urls => Url::delete_id(db, self.key)?,
+            Table::Emails => Email::delete_id(db, self.key)?,
+            Table::Phonenumbers => PhoneNumber::delete_id(db, self.key)?,
+            Table::Devices => Device::delete_id(db, self.key)?,
+            Table::Networks => Network::delete_id(db, self.key)?,
+            Table::NetworkDevices => NetworkDevice::delete_id(db, self.key)?,
+            Table::Accounts => Account::delete_id(db, self.key)?,
+            Table::Breaches => Breach::delete_id(db, self.key)?,
+            Table::BreachEmails => BreachEmail::delete_id(db, self.key)?,
+            Table::Images => Image::delete_id(db, self.key)?,
+            Table::Ports => Port::delete_id(db, self.key)?,
+            Table::Netblocks => Netblock::delete_id(db, self.key)?,
         };
 
         diesel::delete(self)
diff --git a/src/engine/ctx.rs b/src/engine/ctx.rs
index 63127496..aececbe9 100644
--- a/src/engine/ctx.rs
+++ b/src/engine/ctx.rs
@@ -389,6 +389,7 @@ fn ctx<'a>(env: Environment, logger: Arc<Mutex<Box<Reporter>>>) -> (hlua::Lua<'a
     runtime::http_mksession(&mut lua, state.clone());
     runtime::http_request(&mut lua, state.clone());
     runtime::http_send(&mut lua, state.clone());
+    runtime::http_fetch(&mut lua, state.clone());
     runtime::http_fetch_json(&mut lua, state.clone());
     runtime::img_exif(&mut lua, state.clone());
     runtime::img_load(&mut lua, state.clone());
diff --git a/src/models/mod.rs b/src/models/mod.rs
index 998dfd8b..7e34b5e2 100644
--- a/src/models/mod.rs
+++ b/src/models/mod.rs
@@ -1,5 +1,5 @@
 use crate::errors::*;
-use crate::db::{Database, Filter};
+use crate::db::{Database, Table, Filter};
 use crate::fmt;
 use crate::schema::*;
 use std::sync::Arc;
@@ -61,25 +61,9 @@ impl Insert {
         Ok(label)
     }
 
+    #[inline]
     pub fn table(&self) -> &str {
-        match self {
-            Insert::Domain(_) => "domains",
-            Insert::Subdomain(_) => "subdomains",
-            Insert::IpAddr(_) => "ipaddrs",
-            Insert::SubdomainIpAddr(_) => "subdomain_ipaddrs",
-            Insert::Url(_) => "urls",
-            Insert::Email(_) => "emails",
-            Insert::PhoneNumber(_) => "phonenumbers",
-            Insert::Device(_) => "devices",
-            Insert::Network(_) => "networks",
-            Insert::NetworkDevice(_) => "network_devices",
-            Insert::Account(_) => "accounts",
-            Insert::Breach(_) => "breaches",
-            Insert::BreachEmail(_) => "breach_emails",
-            Insert::Image(_) => "images",
-            Insert::Port(_) => "ports",
-            Insert::Netblock(_) => "netblocks",
-        }
+        Table::from(self).into()
     }
 
     pub fn printable(&self, db: &Database) -> Result<String> {
@@ -104,6 +88,29 @@ impl Insert {
     }
 }
 
+impl From<&Insert> for Table {
+    fn from(insert: &Insert) -> Table {
+        match insert {
+            Insert::Domain(_) => Table::Domains,
+            Insert::Subdomain(_) => Table::Subdomains,
+            Insert::IpAddr(_) => Table::Ipaddrs,
+            Insert::SubdomainIpAddr(_) => Table::SubdomainIpaddrs,
+            Insert::Url(_) => Table::Urls,
+            Insert::Email(_) => Table::Emails,
+            Insert::PhoneNumber(_) => Table::Phonenumbers,
+            Insert::Device(_) => Table::Devices,
+            Insert::Network(_) => Table::Networks,
+            Insert::NetworkDevice(_) => Table::NetworkDevices,
+            Insert::Account(_) => Table::Accounts,
+            Insert::Breach(_) => Table::Breaches,
+            Insert::BreachEmail(_) => Table::BreachEmails,
+            Insert::Image(_) => Table::Images,
+            Insert::Port(_) => Table::Ports,
+            Insert::Netblock(_) => Table::Netblocks,
+        }
+    }
+}
+
 #[derive(Debug, Serialize, Deserialize)]
 pub enum Update {
     Subdomain(SubdomainUpdate),
diff --git a/src/registry.rs b/src/registry.rs
index 9b5a6f36..b68b823b 100644
--- a/src/registry.rs
+++ b/src/registry.rs
@@ -3,17 +3,62 @@ use crate::args::{Args, Publish, Install, Search};
 use crate::api::Client;
 use crate::auth;
 use crate::config::Config;
-use crate::engine::Engine;
+use crate::engine::{Engine, Module};
 use colored::Colorize;
 use separator::Separatable;
+use sn0int_common::ModuleID;
+use sn0int_common::api::ModuleInfoResponse;
 use sn0int_common::metadata::Metadata;
 use std::fs;
 use std::path::Path;
 use crate::paths;
 use crate::term;
-use crate::worker;
+use crate::worker::{self, Task, EventSender, LogEvent};
 
 
+pub struct Updater {
+    client: Client,
+}
+
+impl Updater {
+    pub fn new(config: &Config) -> Result<Updater> {
+        let client = Client::new(&config)?;
+        Ok(Updater {
+            client,
+        })
+    }
+
+    #[inline]
+    pub fn query_module(&self, module: &ModuleID) -> Result<ModuleInfoResponse> {
+        self.client.query_module(module)
+    }
+
+    pub fn install(&self, install: &Install) -> Result<String> {
+        let version = match install.version {
+            Some(ref version) => version.to_string(),
+            None => self.client.query_module(&install.module)
+                        .context("Failed to query module infos")?
+                        .latest
+                        .ok_or_else(|| format_err!("Module doesn't have a latest version"))?,
+        };
+
+        let module = self.client.download_module(&install.module, &version)
+            .context("Failed to download module")?;
+
+        let path = paths::module_dir()?
+            .join(format!("{}/{}.lua", install.module.author,
+                                       install.module.name));
+
+        fs::create_dir_all(path.parent().unwrap())
+            .context("Failed to create folder")?;
+
+        fs::write(&path, module.code)
+            .context(format_err!("Failed to write to {:?}", path))?;
+
+        Ok(version)
+    }
+}
+
 pub fn run_publish(_args: &Args, publish: &Publish, config: &Config) -> Result<()> {
     let session = auth::load_token()
         .context("Failed to load auth token")?;
@@ -57,36 +102,101 @@ pub fn run_publish(_args: &Args, publish: &Publish, config: &Config) -> Result<(
     Ok(())
 }
 
-pub fn run_install(install: &Install, config: &Config) -> Result<()> {
-    let client = Client::new(&config)?;
+pub struct InstallTask {
+    install: Install,
+    config: Config,
+}
 
-    let label = format!("Installing {}", install.module);
-    worker::spawn_fn(&label, || {
-        let version = match install.version {
-            Some(ref version) => version.to_string(),
-            None => client.query_module(&install.module)
-                        .context("Failed to query module infos")?
-                        .latest
-                        .ok_or_else(|| format_err!("Module doesn't have a latest version"))?,
-        };
+impl InstallTask {
+    pub fn new(install: Install, config: Config) -> InstallTask {
+        InstallTask {
+            install,
+            config,
+        }
+    }
+}
 
-        let module = client.download_module(&install.module, &version)
-            .context("Failed to download module")?;
+impl Task for InstallTask {
+    #[inline]
+    fn initial_label(name: &str) -> String {
+        format!("Installing {}", name)
+    }
 
-        let path = paths::module_dir()?
-            .join(format!("{}/{}.lua", install.module.author,
-                                       install.module.name));
+    #[inline]
+    fn name(&self) -> String {
+        self.install.module.to_string()
+    }
 
-        fs::create_dir_all(path.parent().unwrap())
-            .context("Failed to create folder")?;
+    fn run(self, tx: &EventSender) -> Result<()> {
+        let client = Updater::new(&self.config)?;
+        let version = client.install(&self.install)?;
+        let label = format!("installed v{}", version);
+        tx.log(LogEvent::Success(label));
+        Ok(())
+    }
+}
 
-        fs::write(&path, module.code)
-            .context(format_err!("Failed to write to {:?}", path))?;
 
+pub fn run_install(arg: &Install, config: &Config) -> Result<()> {
+    let label = format!("Installing {}", arg.module);
+    worker::spawn_fn(&label, || {
+        let client = Updater::new(config)?;
+        client.install(arg)?;
         Ok(())
     }, false)
 }
 
+pub struct UpdateTask {
+    module: Module,
+    config: Config,
+}
+
+impl UpdateTask {
+    pub fn new(module: Module, config: Config) -> UpdateTask {
+        UpdateTask {
+            module,
+            config,
+        }
+    }
+}
+
+impl Task for UpdateTask {
+    #[inline]
+    fn initial_label(name: &str) -> String {
+        format!("Searching for updates: {}", name)
+    }
+
+    #[inline]
+    fn name(&self) -> String {
+        self.module.canonical()
+    }
+
+    fn run(self, tx: &EventSender) -> Result<()> {
+        let installed = self.module.version();
+
+        let client = Updater::new(&self.config)?;
+
+        let infos = client.query_module(&self.module.id())?;
+        debug!("Latest version: {:?}", infos);
+        let latest = infos.latest.ok_or_else(|| format_err!("Module doesn't have any released versions"))?;
+
+        if installed != latest {
+            let label = format!("Updating {}: v{} -> v{}", self.name(), installed, latest);
+            tx.log(LogEvent::Status(label));
+
+            client.install(&Install {
+                module: self.module.id(),
+                version: None,
+            })?;
+
+            let label = format!("updated v{} -> v{}", installed, latest);
+            tx.log(LogEvent::Success(label));
+        }
+
+        Ok(())
+    }
+}
+
 pub fn run_search(engine: &Engine, search: &Search, config: &Config) -> Result<()> {
     let client = Client::new(&config)?;
 
diff --git a/src/runtime/db.rs b/src/runtime/db.rs
index 26805b3b..c6abdd25 100644
--- a/src/runtime/db.rs
+++ b/src/runtime/db.rs
@@ -26,10 +26,10 @@ fn into_insert(family: Family, object: LuaJsonValue, state: &Arc<State>) -> Resu
         Family::Subdomain => {
             Insert::Subdomain(try_into_new::<InsertSubdomain>(object, state)?)
         },
-        Family::IpAddr => {
+        Family::Ipaddr => {
             Insert::IpAddr(try_into_new::<InsertIpAddr>(object, state)?)
         },
-        Family::SubdomainIpAddr => {
+        Family::SubdomainIpaddr => {
             Insert::SubdomainIpAddr(try_into_new::<InsertSubdomainIpAddr>(object, state)?)
         },
         Family::Url => {
@@ -38,7 +38,7 @@ fn into_insert(family: Family, object: LuaJsonValue, state: &Arc<State>) -> Resu
         Family::Email => {
             Insert::Email(try_into_new::<InsertEmail>(object, state)?)
         },
-        Family::PhoneNumber => {
+        Family::Phonenumber => {
             Insert::PhoneNumber(try_into_new::<InsertPhoneNumber>(object, state)?)
         },
         Family::Device => {
@@ -75,7 +75,7 @@ fn into_insert(family: Family, object: LuaJsonValue, state: &Arc<State>) -> Resu
 pub fn db_add(lua: &mut hlua::Lua, state: Arc<State>) {
     lua.set("db_add", hlua::function2(move |family: String, object: AnyLuaValue| -> Result<Option<i32>> {
         let family = Family::from_str(&family)
-            .map_err(|e| state.set_error(e))?;
+            .map_err(|e| state.set_error(e.into()))?;
         let object = LuaJsonValue::from(object);
 
         let object = into_insert(family, object, &state)
@@ -89,7 +89,7 @@ pub fn db_add(lua: &mut hlua::Lua, state: Arc<State>) {
 pub fn db_add_ttl(lua: &mut hlua::Lua, state: Arc<State>) {
     lua.set("db_add_ttl", hlua::function3(move |family: String, object: AnyLuaValue, ttl: i32| -> Result<Option<i32>> {
         let family = Family::from_str(&family)
-            .map_err(|e| state.set_error(e))?;
+            .map_err(|e| state.set_error(e.into()))?;
         let object = LuaJsonValue::from(object);
 
         let object = into_insert(family, object, &state)
@@ -103,7 +103,7 @@ pub fn db_add_ttl(lua: &mut hlua::Lua, state: Arc<State>) {
 pub fn db_select(lua: &mut hlua::Lua, state: Arc<State>) {
     lua.set("db_select", hlua::function2(move |family: String, value: String| -> Result<Option<i32>> {
         let family = Family::from_str(&family)
-            .map_err(|e| state.set_error(e))?;
+            .map_err(|e| state.set_error(e.into()))?;
 
         state.db_select(family, value)
             .map_err(|e| state.set_error(e))
@@ -133,7 +133,7 @@ fn gen_changeset<T: Model, U: Updateable<T>>(object: LuaJsonValue, mut update: L
 pub fn db_update(lua: &mut hlua::Lua, state: Arc<State>) {
     lua.set("db_update", hlua::function3(move |family: String, object: AnyLuaValue, update: AnyLuaValue| -> Result<Option<i32>> {
         let family = Family::from_str(&family)
-            .map_err(|e| state.set_error(e))?;
+            .map_err(|e| state.set_error(e.into()))?;
         let object = LuaJsonValue::from(object);
         let update = LuaJsonValue::from(update);
 
@@ -141,14 +141,14 @@ pub fn db_update(lua: &mut hlua::Lua, state: Arc<State>) {
             Family::Domain => bail!("Domain doesn't have mutable fields"),
             Family::Subdomain => gen_changeset::<Subdomain, SubdomainUpdate>(object, update)
                 .map(|(id, v, u)| (id, v, Update::Subdomain(u))),
-            Family::IpAddr => gen_changeset::<IpAddr, IpAddrUpdate>(object, update)
+            Family::Ipaddr => gen_changeset::<IpAddr, IpAddrUpdate>(object, update)
                 .map(|(id, v, u)| (id, v, Update::IpAddr(u))),
-            Family::SubdomainIpAddr => bail!("Subdomain-IpAddr doesn't have mutable fields"),
+            Family::SubdomainIpaddr => bail!("Subdomain-IpAddr doesn't have mutable fields"),
             Family::Url => gen_changeset::<Url, UrlUpdate>(object, update)
                 .map(|(id, v, u)| (id, v, Update::Url(u))),
             Family::Email => gen_changeset::<Email, EmailUpdate>(object, update)
                 .map(|(id, v, u)| (id, v, Update::Email(u))),
-            Family::PhoneNumber => gen_changeset::<PhoneNumber, PhoneNumberUpdate>(object, update)
+            Family::Phonenumber => gen_changeset::<PhoneNumber, PhoneNumberUpdate>(object, update)
                 .map(|(id, v, u)| (id, v, Update::PhoneNumber(u))),
             Family::Device => gen_changeset::<Device, DeviceUpdate>(object, update)
                 .map(|(id, v, u)| (id, v, Update::Device(u))),
diff --git a/src/runtime/gfx.rs b/src/runtime/gfx.rs
index 8176586e..1b02ac53 100644
--- a/src/runtime/gfx.rs
+++ b/src/runtime/gfx.rs
@@ -95,9 +95,8 @@ mod tests {
             req = http_request(session, 'GET', 'https://www.kernel.org/theme/images/logos/tux.png', {
                 into_blob=true,
             })
-            r = http_send(req)
+            r = http_fetch(req)
             if last_err() then return end
-            if r['status'] ~= 200 then return 'http error: ' .. r['status'] end
 
             img = img_load(r['blob'])
 
@@ -125,9 +124,8 @@ mod tests {
             req = http_request(session, 'GET', 'https://www.kernel.org/theme/images/logos/tux.png', {
                 into_blob=true,
             })
-            r = http_send(req)
+            r = http_fetch(req)
             if last_err() then return end
-            if r['status'] ~= 200 then return 'http error: ' .. r['status'] end
 
             nudity = img_nudity(r['blob'])
 
@@ -155,10 +153,9 @@ mod tests {
             req = http_request(session, 'GET', url, {
                 into_blob=true,
             })
-            r = http_send(req)
+            r = http_fetch(req)
             if last_err() then return end
             print(r)
-            if r['status'] ~= 200 then return 'wrong status code' end
 
             location = img_exif(r['blob'])
             print(location)
diff --git a/src/runtime/http.rs b/src/runtime/http.rs
index 815934d5..6980ad1b 100644
--- a/src/runtime/http.rs
+++ b/src/runtime/http.rs
@@ -31,7 +31,29 @@ pub fn http_send(lua: &mut hlua::Lua, state: Arc<State>) {
             .context("invalid http request object")
             .map_err(|err| state.set_error(err.into()))?;
 
-        req.send_lua(state.as_ref())
+        let resp = req.send(state.as_ref())
+            .map_err(|err| state.set_error(err))?;
+
+        req.response_to_lua(state.as_ref(), resp)
+            .map_err(|err| state.set_error(err))
+            .map(|resp| resp.into())
+    }))
+}
+
+pub fn http_fetch(lua: &mut hlua::Lua, state: Arc<State>) {
+    lua.set("http_fetch", hlua::function1(move |request: AnyLuaValue| -> Result<AnyLuaValue> {
+        let req = HttpRequest::try_from(request)
+            .context("invalid http request object")
+            .map_err(|err| state.set_error(err.into()))?;
+
+        let resp = req.send(state.as_ref())
+            .map_err(|err| state.set_error(err))?;
+
+        if resp.status < 200 || resp.status > 299 {
+            return Err(state.set_error(format_err!("http status error: {}", resp.status)));
+        }
+
+        req.response_to_lua(state.as_ref(), resp)
             .map_err(|err| state.set_error(err))
             .map(|resp| resp.into())
     }))
@@ -167,6 +189,27 @@ mod tests {
     #[test]
     #[ignore]
     fn verify_fetch_ok() {
+        let script = Script::load_unchecked(r#"
+        function run()
+            session = http_mksession()
+            req = http_request(session, "GET", "https://httpbin.org/anything", {})
+            x = http_fetch(req)
+            if last_err() then return end
+
+            o = json_decode(x['text'])
+            if last_err() then return end
+
+            if o['method'] ~= 'GET' then
+                return 'unexpected response'
+            end
+        end
+        "#).expect("failed to load script");
+        script.test().expect("Script failed");
+    }
+
+    #[test]
+    #[ignore]
+    fn verify_fetch_json_ok() {
         let script = Script::load_unchecked(r#"
         function run()
             session = http_mksession()
@@ -185,6 +228,19 @@ mod tests {
     #[test]
     #[ignore]
     fn verify_fetch_404() {
+        let script = Script::load_unchecked(r#"
+        function run()
+            session = http_mksession()
+            req = http_request(session, "GET", "https://httpbin.org/status/404", {})
+            x = http_fetch(req)
+        end
+        "#).expect("failed to load script");
+        script.test().err().expect("Script should have failed");
+    }
+
+    #[test]
+    #[ignore]
+    fn verify_fetch_json_404() {
         let script = Script::load_unchecked(r#"
         function run()
             session = http_mksession()
@@ -197,7 +253,7 @@ mod tests {
 
     #[test]
     #[ignore]
-    fn verify_fetch_invalid_json() {
+    fn verify_fetch_json_invalid() {
         let script = Script::load_unchecked(r#"
         function run()
             session = http_mksession()
diff --git a/src/term.rs b/src/term.rs
index a8add846..9f862419 100644
--- a/src/term.rs
+++ b/src/term.rs
@@ -78,6 +78,8 @@ pub trait SpinLogger {
 
     fn debug(&mut self, line: &str);
 
+    fn success(&mut self, line: &str);
+
     fn error(&mut self, line: &str);
 
     fn warn(&mut self, line: &str);
@@ -85,6 +87,8 @@ pub trait SpinLogger {
     fn warn_once(&mut self, line: &str);
 
     fn status(&mut self, status: String);
+
+    fn stacked_status(&mut self, name: &String, status: String);
 }
 
 pub struct Spinner {
@@ -164,6 +168,11 @@ impl SpinLogger for Spinner {
         println!("\r\x1b[2K\x1b[1m[\x1b[34m{}\x1b[0;1m]\x1b[0m {}", '#', line);
     }
 
+    fn success(&mut self, line: &str) {
+        if self.dummy { return; }
+        println!("\r\x1b[2K\x1b[1m[\x1b[32m{}\x1b[0;1m]\x1b[0m {}", '+', line);
+    }
+
     fn error(&mut self, line: &str) {
         if self.dummy { return; }
         println!("\r\x1b[2K\x1b[1m[\x1b[31m{}\x1b[0;1m]\x1b[0m {}", '-', line);
@@ -185,6 +194,11 @@ impl SpinLogger for Spinner {
     fn status(&mut self, status: String) {
         self.status = status;
     }
+
+    #[inline]
+    fn stacked_status(&mut self, _name: &String, status: String) {
+        self.status = status;
+    }
 }
 
 pub fn success(line: &str) {
@@ -321,6 +335,11 @@ impl SpinLogger for StackedSpinners {
         println!("\r\x1b[2K\x1b[1m[\x1b[34m{}\x1b[0;1m]\x1b[0m {}", '#', line);
     }
 
+    fn success(&mut self, line: &str) {
+        self.jump2start();
+        println!("\r\x1b[2K\x1b[1m[\x1b[32m{}\x1b[0;1m]\x1b[0m {}", '+', line);
+    }
+
     fn error(&mut self, line: &str) {
         self.jump2start();
         println!("\r\x1b[2K\x1b[1m[\x1b[31m{}\x1b[0;1m]\x1b[0m {}", '-', line);
@@ -342,6 +361,12 @@ impl SpinLogger for StackedSpinners {
     fn status(&mut self, status: String) {
         self.error(&format!("TODO: set status: {:?}", status));
     }
+
+    fn stacked_status(&mut self, name: &String, status: String) {
+        if let Some(spinner) = self.spinners.get_mut(name) {
+            spinner.status(status);
+        }
+    }
 }
 
 pub struct PrefixedLogger<'a, T: 'a + SpinLogger> {
@@ -370,6 +395,11 @@ impl<'a, T: SpinLogger> SpinLogger for PrefixedLogger<'a, T> {
         self.s.debug(&format!("{:50}: {}", self.prefix, line))
     }
 
+    #[inline]
+    fn success(&mut self, line: &str) {
+        self.s.success(&format!("{:50}: {}", self.prefix, line))
+    }
+
     #[inline]
     fn error(&mut self, line: &str) {
         self.s.error(&format!("{:50}: {}", self.prefix, line))
@@ -387,6 +417,11 @@ impl<'a, T: SpinLogger> SpinLogger for PrefixedLogger<'a, T> {
 
     #[inline]
     fn status(&mut self, status: String) {
-        self.s.status(format!("{:50}: {}", self.prefix, status))
+        self.s.stacked_status(&self.prefix, status)
+    }
+
+    #[inline]
+    fn stacked_status(&mut self, prefix: &String, status: String) {
+        self.s.stacked_status(prefix, status)
     }
 }
diff --git a/src/update.rs b/src/update.rs
index 3262216a..756c8341 100644
--- a/src/update.rs
+++ b/src/update.rs
@@ -3,6 +3,7 @@ use crate::api::Client;
 use crate::config::Config;
 use crate::engine;
 use crate::paths;
+use std::collections::HashSet;
 use std::fs;
 use std::path::PathBuf;
 use std::time::{SystemTime, UNIX_EPOCH};
@@ -19,15 +20,17 @@ pub struct AutoUpdater {
     #[serde(default)]
     last_update: u64,
     #[serde(default)]
-    outdated: u64,
+    outdated: HashSet<String>,
 }
 
 impl AutoUpdater {
+    #[inline]
     fn path() -> Result<PathBuf> {
         let path = paths::data_dir()?;
         Ok(path.join("autoupdate.json"))
     }
 
+    #[inline]
     fn now() -> u64 {
         SystemTime::now()
             .duration_since(UNIX_EPOCH)
@@ -36,8 +39,18 @@ impl AutoUpdater {
     }
 
     #[inline]
-    pub fn outdated(&self) -> u64 {
-        self.outdated
+    pub fn outdated(&self) -> usize {
+        self.outdated.len()
+    }
+
+    #[inline]
+    pub fn updated(&mut self, module: &str) {
+        self.outdated.remove(module);
+    }
+
+    #[inline]
+    pub fn is_outdated(&self, module: &str) -> bool {
+        self.outdated.contains(module)
     }
 
     pub fn load() -> Result<AutoUpdater> {
@@ -56,10 +69,6 @@ impl AutoUpdater {
         Ok(())
     }
 
-    pub fn all_updated(&mut self) {
-        self.outdated = 0;
-    }
-
     pub fn check_background(mut self, config: &Config, modules: Vec<&engine::Module>) {
         if config.core.no_autoupdate {
             debug!("Auto update has been disabled, skipping");
@@ -94,7 +103,7 @@ impl AutoUpdater {
         let latest = client.latest_release()?;
 
         if latest.time != self.registry {
-            let mut outdated = 0;
+            let mut outdated = HashSet::new();
 
             for module in modules {
                 if module.is_private() {
@@ -108,8 +117,9 @@ impl AutoUpdater {
 
                     if let Some(latest) = infos.latest {
                         if installed != latest {
-                            debug!("Outdated: {}: {:?} -> {:?}", module.canonical(), installed, latest);
-                            outdated += 1;
+                            let canonical = module.canonical();
+                            debug!("Outdated: {}: {:?} -> {:?}", canonical, installed, latest);
+                            outdated.insert(canonical);
                         }
                     }
                 }
diff --git a/src/web.rs b/src/web.rs
index cf12958a..b73cb8d3 100644
--- a/src/web.rs
+++ b/src/web.rs
@@ -215,27 +215,24 @@ impl HttpRequest {
             .with_timeout(self.timeout)
             .wait_for_response()?;
 
+        for cookie in &res.cookies {
+            HttpRequest::register_cookies_on_state(&self.session, state, cookie);
+        }
+
         Ok(res)
     }
 
-    pub fn send_lua(&self, state: &State) -> Result<LuaMap> {
-        let res = self.send(state)?;
-
+    pub fn response_to_lua(&self, state: &State, res: Response) -> Result<LuaMap> {
         // map result to LuaMap
         let mut resp = LuaMap::new();
         resp.insert_num("status", f64::from(res.status));
 
-        for cookie in &res.cookies {
-            HttpRequest::register_cookies_on_state(&self.session, state, cookie);
-        }
-
         let mut headers = LuaMap::new();
         for (key, value) in res.headers {
             headers.insert_str(key.to_lowercase(), value);
         }
         resp.insert("headers", headers);
 
-
         if self.into_blob {
             let blob = Blob::create(res.body);
             let id = state.register_blob(blob);
@@ -286,6 +283,7 @@ impl Into<AnyLuaValue> for HttpRequest {
 pub struct CookieJar(HashMap<String, String>);
 
 impl CookieJar {
+    #[inline(always)]
     pub fn register_in_jar(&mut self, key: String, value: String) {
         self.0.insert(key, value);
     }
@@ -294,6 +292,7 @@ impl CookieJar {
 impl Deref for CookieJar {
     type Target = HashMap<String, String>;
 
+    #[inline(always)]
     fn deref(&self) -> &Self::Target {
         &self.0
     }
diff --git a/src/worker.rs b/src/worker.rs
index 0028cead..1d7a762a 100644
--- a/src/worker.rs
+++ b/src/worker.rs
@@ -44,8 +44,8 @@ pub enum Event2 {
 
 #[derive(Debug)]
 pub struct MultiEvent {
-    name: String,
-    event: Event2,
+    pub name: String,
+    pub event: Event2,
 }
 
 impl MultiEvent {
@@ -64,6 +64,7 @@ pub struct EventSender {
 }
 
 impl EventSender {
+    #[inline]
     pub fn new(name: String, tx: channel::Sender<MultiEvent>) -> EventSender {
         EventSender {
             name,
@@ -71,6 +72,12 @@ impl EventSender {
         }
     }
 
+    #[inline]
+    pub fn log(&self, log: LogEvent) {
+        self.send(Event2::Log(log));
+    }
+
+    #[inline]
     pub fn send(&self, event: Event2) {
         self.tx.send(MultiEvent::new(self.name.clone(), event)).unwrap();
     }
@@ -93,6 +100,7 @@ pub enum ExitEvent {
 pub enum LogEvent {
     Info(String),
     Debug(String),
+    Success(String),
     Error(String),
     Warn(String),
     WarnOnce(String),
@@ -104,6 +112,7 @@ impl LogEvent {
         match self {
             LogEvent::Info(info) => spinner.log(&info),
             LogEvent::Debug(debug) => spinner.debug(&debug),
+            LogEvent::Success(success) => spinner.success(&success),
             LogEvent::Error(error) => spinner.error(&error),
             LogEvent::Warn(warn) => spinner.warn(&warn),
             LogEvent::WarnOnce(warn) => spinner.warn_once(&warn),
@@ -399,3 +408,91 @@ pub fn spawn_fn<F, T>(label: &str, f: F, clear: bool) -> Result<T>
 
     result
 }
+
+pub trait Task {
+    fn initial_label(name: &str) -> String;
+
+    fn name(&self) -> String;
+
+    fn run(self, tx: &EventSender) -> Result<()>;
+}
+
+pub fn spawn_multi<T: Task, F>(tasks: Vec<T>, mut done_fn: F, threads: usize) -> Result<()>
+    where
+        F: FnMut(String),
+        T: 'static + Send
+{
+    // This function hangs if args is empty, so return early if that's the case
+    if tasks.is_empty() {
+        return Ok(());
+    }
+
+    let mut expected = 0;
+    let mut stack = StackedSpinners::new();
+
+    let (tx, rx) = channel::bounded(1);
+    let pool = ThreadPool::new(threads);
+
+    for task in tasks {
+        let tx = tx.clone();
+        pool.execute(move || {
+            let name = task.name();
+            let tx = EventSender::new(name, tx);
+
+            tx.send(Event2::Start);
+
+            let exit = match task.run(&tx) {
+                Ok(_) => ExitEvent::Ok,
+                Err(err) => ExitEvent::Err(err.to_string()),
+            };
+
+            tx.send(Event2::Exit(exit));
+        });
+        expected += 1;
+    }
+
+    let timeout = Duration::from_millis(100);
+    loop {
+        select! {
+            recv(rx) -> msg => match msg.ok() {
+                Some(event) => {
+                    let (name, event) = (event.name, event.event);
+
+                    match event {
+                        Event2::Start => {
+                            let label = T::initial_label(&name);
+                            stack.add(name, label);
+                        },
+                        Event2::Log(log) => log.apply(&mut stack.prefixed(&name)),
+                        Event2::Database(_) => (),
+                        Event2::Blob(_) => (),
+                        Event2::Exit(event) => {
+                            debug!("Received exit: {:?} -> {:?}", name, event);
+                            stack.remove(&name);
+
+                            match event {
+                                ExitEvent::Ok => done_fn(name),
+                                ExitEvent::Err(err) => {
+                                    LogEvent::Error(err).apply(&mut stack.prefixed(&name));
+                                },
+                                ExitEvent::SetupFailed(_) => (),
+                            }
+
+                            // if every task reported back, exit
+                            expected -= 1;
+                            info!("spawn_all is expecting {} more results", expected);
+                            if expected == 0 {
+                                break;
+                            }
+                        },
+                    }
+                },
+                None => break, // channel closed
+            },
+            default(timeout) => (),
+        }
+        stack.tick();
+    }
+
+    Ok(())
+}


Test patch: