diff --git a/README.txt b/README.txt
index d840874a5483f78bd2827ce9960356b6768b04f3..046e109404104e53620f98e2a7a8debb6e140dd7 100644
--- a/README.txt
+++ b/README.txt
@@ -53,6 +53,8 @@ install mingw32-make
  > pacman -S mingw-w64-{i686,x86_64}-make 
 install cmake mingw32 and mingw64
  > pacman -S mingw-w64-{i686,x86_64}-cmake mingw-w64-{i686,x86_64}-extra-cmake-modules
+install cmake cache
+ >pacman -S mingw-w64-{i686,x86_64}-ccache
 install opencl headers
  > pacman -S mingw-w64-{i686,x86_64}-opencl-headers
 install lapack: openblas
diff --git a/tools/msys/mingw32/bin/ccache.exe b/tools/msys/mingw32/bin/ccache.exe
new file mode 100644
index 0000000000000000000000000000000000000000..36012a2c06c4156d153e0e523a40b24167feb271
Binary files /dev/null and b/tools/msys/mingw32/bin/ccache.exe differ
diff --git a/tools/msys/mingw32/bin/libhiredis.dll b/tools/msys/mingw32/bin/libhiredis.dll
new file mode 100644
index 0000000000000000000000000000000000000000..c004656e704d7c0eef1bbcbdce8f8c7e4cb5494a
Binary files /dev/null and b/tools/msys/mingw32/bin/libhiredis.dll differ
diff --git a/tools/msys/mingw32/bin/libhiredis_ssl.dll b/tools/msys/mingw32/bin/libhiredis_ssl.dll
new file mode 100644
index 0000000000000000000000000000000000000000..b84b3fe668c066f341485e022a0fad238048c320
Binary files /dev/null and b/tools/msys/mingw32/bin/libhiredis_ssl.dll differ
diff --git a/tools/msys/mingw32/include/hiredis/adapters/ae.h b/tools/msys/mingw32/include/hiredis/adapters/ae.h
new file mode 100644
index 0000000000000000000000000000000000000000..660d82eb0cecebbd574d1743bfa94090a408479d
--- /dev/null
+++ b/tools/msys/mingw32/include/hiredis/adapters/ae.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of Redis nor the names of its contributors may be used
+ *     to endorse or promote products derived from this software without
+ *     specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __HIREDIS_AE_H__
+#define __HIREDIS_AE_H__
+#include <sys/types.h>
+#include <ae.h>
+#include "../hiredis.h"
+#include "../async.h"
+
+typedef struct redisAeEvents {
+    redisAsyncContext *context;
+    aeEventLoop *loop;
+    int fd;
+    int reading, writing;
+} redisAeEvents;
+
+static void redisAeReadEvent(aeEventLoop *el, int fd, void *privdata, int mask) {
+    ((void)el); ((void)fd); ((void)mask);
+
+    redisAeEvents *e = (redisAeEvents*)privdata;
+    redisAsyncHandleRead(e->context);
+}
+
+static void redisAeWriteEvent(aeEventLoop *el, int fd, void *privdata, int mask) {
+    ((void)el); ((void)fd); ((void)mask);
+
+    redisAeEvents *e = (redisAeEvents*)privdata;
+    redisAsyncHandleWrite(e->context);
+}
+
+static void redisAeAddRead(void *privdata) {
+    redisAeEvents *e = (redisAeEvents*)privdata;
+    aeEventLoop *loop = e->loop;
+    if (!e->reading) {
+        e->reading = 1;
+        aeCreateFileEvent(loop,e->fd,AE_READABLE,redisAeReadEvent,e);
+    }
+}
+
+static void redisAeDelRead(void *privdata) {
+    redisAeEvents *e = (redisAeEvents*)privdata;
+    aeEventLoop *loop = e->loop;
+    if (e->reading) {
+        e->reading = 0;
+        aeDeleteFileEvent(loop,e->fd,AE_READABLE);
+    }
+}
+
+static void redisAeAddWrite(void *privdata) {
+    redisAeEvents *e = (redisAeEvents*)privdata;
+    aeEventLoop *loop = e->loop;
+    if (!e->writing) {
+        e->writing = 1;
+        aeCreateFileEvent(loop,e->fd,AE_WRITABLE,redisAeWriteEvent,e);
+    }
+}
+
+static void redisAeDelWrite(void *privdata) {
+    redisAeEvents *e = (redisAeEvents*)privdata;
+    aeEventLoop *loop = e->loop;
+    if (e->writing) {
+        e->writing = 0;
+        aeDeleteFileEvent(loop,e->fd,AE_WRITABLE);
+    }
+}
+
+static void redisAeCleanup(void *privdata) {
+    redisAeEvents *e = (redisAeEvents*)privdata;
+    redisAeDelRead(privdata);
+    redisAeDelWrite(privdata);
+    hi_free(e);
+}
+
+static int redisAeAttach(aeEventLoop *loop, redisAsyncContext *ac) {
+    redisContext *c = &(ac->c);
+    redisAeEvents *e;
+
+    /* Nothing should be attached when something is already attached */
+    if (ac->ev.data != NULL)
+        return REDIS_ERR;
+
+    /* Create container for context and r/w events */
+    e = (redisAeEvents*)hi_malloc(sizeof(*e));
+    if (e == NULL)
+        return REDIS_ERR;
+
+    e->context = ac;
+    e->loop = loop;
+    e->fd = c->fd;
+    e->reading = e->writing = 0;
+
+    /* Register functions to start/stop listening for events */
+    ac->ev.addRead = redisAeAddRead;
+    ac->ev.delRead = redisAeDelRead;
+    ac->ev.addWrite = redisAeAddWrite;
+    ac->ev.delWrite = redisAeDelWrite;
+    ac->ev.cleanup = redisAeCleanup;
+    ac->ev.data = e;
+
+    return REDIS_OK;
+}
+#endif
diff --git a/tools/msys/mingw32/include/hiredis/adapters/glib.h b/tools/msys/mingw32/include/hiredis/adapters/glib.h
new file mode 100644
index 0000000000000000000000000000000000000000..ad59dd14275183254313ffe505ea8b5b1d9c33ba
--- /dev/null
+++ b/tools/msys/mingw32/include/hiredis/adapters/glib.h
@@ -0,0 +1,156 @@
+#ifndef __HIREDIS_GLIB_H__
+#define __HIREDIS_GLIB_H__
+
+#include <glib.h>
+
+#include "../hiredis.h"
+#include "../async.h"
+
+typedef struct
+{
+    GSource source;
+    redisAsyncContext *ac;
+    GPollFD poll_fd;
+} RedisSource;
+
+static void
+redis_source_add_read (gpointer data)
+{
+    RedisSource *source = (RedisSource *)data;
+    g_return_if_fail(source);
+    source->poll_fd.events |= G_IO_IN;
+    g_main_context_wakeup(g_source_get_context((GSource *)data));
+}
+
+static void
+redis_source_del_read (gpointer data)
+{
+    RedisSource *source = (RedisSource *)data;
+    g_return_if_fail(source);
+    source->poll_fd.events &= ~G_IO_IN;
+    g_main_context_wakeup(g_source_get_context((GSource *)data));
+}
+
+static void
+redis_source_add_write (gpointer data)
+{
+    RedisSource *source = (RedisSource *)data;
+    g_return_if_fail(source);
+    source->poll_fd.events |= G_IO_OUT;
+    g_main_context_wakeup(g_source_get_context((GSource *)data));
+}
+
+static void
+redis_source_del_write (gpointer data)
+{
+    RedisSource *source = (RedisSource *)data;
+    g_return_if_fail(source);
+    source->poll_fd.events &= ~G_IO_OUT;
+    g_main_context_wakeup(g_source_get_context((GSource *)data));
+}
+
+static void
+redis_source_cleanup (gpointer data)
+{
+    RedisSource *source = (RedisSource *)data;
+
+    g_return_if_fail(source);
+
+    redis_source_del_read(source);
+    redis_source_del_write(source);
+    /*
+     * It is not our responsibility to remove ourself from the
+     * current main loop. However, we will remove the GPollFD.
+     */
+    if (source->poll_fd.fd >= 0) {
+        g_source_remove_poll((GSource *)data, &source->poll_fd);
+        source->poll_fd.fd = -1;
+    }
+}
+
+static gboolean
+redis_source_prepare (GSource *source,
+                      gint    *timeout_)
+{
+    RedisSource *redis = (RedisSource *)source;
+    *timeout_ = -1;
+    return !!(redis->poll_fd.events & redis->poll_fd.revents);
+}
+
+static gboolean
+redis_source_check (GSource *source)
+{
+    RedisSource *redis = (RedisSource *)source;
+    return !!(redis->poll_fd.events & redis->poll_fd.revents);
+}
+
+static gboolean
+redis_source_dispatch (GSource      *source,
+                       GSourceFunc   callback,
+                       gpointer      user_data)
+{
+    RedisSource *redis = (RedisSource *)source;
+
+    if ((redis->poll_fd.revents & G_IO_OUT)) {
+        redisAsyncHandleWrite(redis->ac);
+        redis->poll_fd.revents &= ~G_IO_OUT;
+    }
+
+    if ((redis->poll_fd.revents & G_IO_IN)) {
+        redisAsyncHandleRead(redis->ac);
+        redis->poll_fd.revents &= ~G_IO_IN;
+    }
+
+    if (callback) {
+        return callback(user_data);
+    }
+
+    return TRUE;
+}
+
+static void
+redis_source_finalize (GSource *source)
+{
+    RedisSource *redis = (RedisSource *)source;
+
+    if (redis->poll_fd.fd >= 0) {
+        g_source_remove_poll(source, &redis->poll_fd);
+        redis->poll_fd.fd = -1;
+    }
+}
+
+static GSource *
+redis_source_new (redisAsyncContext *ac)
+{
+    static GSourceFuncs source_funcs = {
+        .prepare  = redis_source_prepare,
+        .check     = redis_source_check,
+        .dispatch = redis_source_dispatch,
+        .finalize = redis_source_finalize,
+    };
+    redisContext *c = &ac->c;
+    RedisSource *source;
+
+    g_return_val_if_fail(ac != NULL, NULL);
+
+    source = (RedisSource *)g_source_new(&source_funcs, sizeof *source);
+    if (source == NULL)
+        return NULL;
+
+    source->ac = ac;
+    source->poll_fd.fd = c->fd;
+    source->poll_fd.events = 0;
+    source->poll_fd.revents = 0;
+    g_source_add_poll((GSource *)source, &source->poll_fd);
+
+    ac->ev.addRead = redis_source_add_read;
+    ac->ev.delRead = redis_source_del_read;
+    ac->ev.addWrite = redis_source_add_write;
+    ac->ev.delWrite = redis_source_del_write;
+    ac->ev.cleanup = redis_source_cleanup;
+    ac->ev.data = source;
+
+    return (GSource *)source;
+}
+
+#endif /* __HIREDIS_GLIB_H__ */
diff --git a/tools/msys/mingw32/include/hiredis/adapters/ivykis.h b/tools/msys/mingw32/include/hiredis/adapters/ivykis.h
new file mode 100644
index 0000000000000000000000000000000000000000..179f6ab523701fa8a54bcb13db2608d7beb4f079
--- /dev/null
+++ b/tools/msys/mingw32/include/hiredis/adapters/ivykis.h
@@ -0,0 +1,84 @@
+#ifndef __HIREDIS_IVYKIS_H__
+#define __HIREDIS_IVYKIS_H__
+#include <iv.h>
+#include "../hiredis.h"
+#include "../async.h"
+
+typedef struct redisIvykisEvents {
+    redisAsyncContext *context;
+    struct iv_fd fd;
+} redisIvykisEvents;
+
+static void redisIvykisReadEvent(void *arg) {
+    redisAsyncContext *context = (redisAsyncContext *)arg;
+    redisAsyncHandleRead(context);
+}
+
+static void redisIvykisWriteEvent(void *arg) {
+    redisAsyncContext *context = (redisAsyncContext *)arg;
+    redisAsyncHandleWrite(context);
+}
+
+static void redisIvykisAddRead(void *privdata) {
+    redisIvykisEvents *e = (redisIvykisEvents*)privdata;
+    iv_fd_set_handler_in(&e->fd, redisIvykisReadEvent);
+}
+
+static void redisIvykisDelRead(void *privdata) {
+    redisIvykisEvents *e = (redisIvykisEvents*)privdata;
+    iv_fd_set_handler_in(&e->fd, NULL);
+}
+
+static void redisIvykisAddWrite(void *privdata) {
+    redisIvykisEvents *e = (redisIvykisEvents*)privdata;
+    iv_fd_set_handler_out(&e->fd, redisIvykisWriteEvent);
+}
+
+static void redisIvykisDelWrite(void *privdata) {
+    redisIvykisEvents *e = (redisIvykisEvents*)privdata;
+    iv_fd_set_handler_out(&e->fd, NULL);
+}
+
+static void redisIvykisCleanup(void *privdata) {
+    redisIvykisEvents *e = (redisIvykisEvents*)privdata;
+
+    iv_fd_unregister(&e->fd);
+    hi_free(e);
+}
+
+static int redisIvykisAttach(redisAsyncContext *ac) {
+    redisContext *c = &(ac->c);
+    redisIvykisEvents *e;
+
+    /* Nothing should be attached when something is already attached */
+    if (ac->ev.data != NULL)
+        return REDIS_ERR;
+
+    /* Create container for context and r/w events */
+    e = (redisIvykisEvents*)hi_malloc(sizeof(*e));
+    if (e == NULL)
+        return REDIS_ERR;
+
+    e->context = ac;
+
+    /* Register functions to start/stop listening for events */
+    ac->ev.addRead = redisIvykisAddRead;
+    ac->ev.delRead = redisIvykisDelRead;
+    ac->ev.addWrite = redisIvykisAddWrite;
+    ac->ev.delWrite = redisIvykisDelWrite;
+    ac->ev.cleanup = redisIvykisCleanup;
+    ac->ev.data = e;
+
+    /* Initialize and install read/write events */
+    IV_FD_INIT(&e->fd);
+    e->fd.fd = c->fd;
+    e->fd.handler_in = redisIvykisReadEvent;
+    e->fd.handler_out = redisIvykisWriteEvent;
+    e->fd.handler_err = NULL;
+    e->fd.cookie = e->context;
+
+    iv_fd_register(&e->fd);
+
+    return REDIS_OK;
+}
+#endif
diff --git a/tools/msys/mingw32/include/hiredis/adapters/libev.h b/tools/msys/mingw32/include/hiredis/adapters/libev.h
new file mode 100644
index 0000000000000000000000000000000000000000..e1e7bbd99c9473cffe6f7ce0c7b546550e834d00
--- /dev/null
+++ b/tools/msys/mingw32/include/hiredis/adapters/libev.h
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of Redis nor the names of its contributors may be used
+ *     to endorse or promote products derived from this software without
+ *     specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __HIREDIS_LIBEV_H__
+#define __HIREDIS_LIBEV_H__
+#include <stdlib.h>
+#include <sys/types.h>
+#include <ev.h>
+#include "../hiredis.h"
+#include "../async.h"
+
+typedef struct redisLibevEvents {
+    redisAsyncContext *context;
+    struct ev_loop *loop;
+    int reading, writing;
+    ev_io rev, wev;
+    ev_timer timer;
+} redisLibevEvents;
+
+static void redisLibevReadEvent(EV_P_ ev_io *watcher, int revents) {
+#if EV_MULTIPLICITY
+    ((void)loop);
+#endif
+    ((void)revents);
+
+    redisLibevEvents *e = (redisLibevEvents*)watcher->data;
+    redisAsyncHandleRead(e->context);
+}
+
+static void redisLibevWriteEvent(EV_P_ ev_io *watcher, int revents) {
+#if EV_MULTIPLICITY
+    ((void)loop);
+#endif
+    ((void)revents);
+
+    redisLibevEvents *e = (redisLibevEvents*)watcher->data;
+    redisAsyncHandleWrite(e->context);
+}
+
+static void redisLibevAddRead(void *privdata) {
+    redisLibevEvents *e = (redisLibevEvents*)privdata;
+    struct ev_loop *loop = e->loop;
+    ((void)loop);
+    if (!e->reading) {
+        e->reading = 1;
+        ev_io_start(EV_A_ &e->rev);
+    }
+}
+
+static void redisLibevDelRead(void *privdata) {
+    redisLibevEvents *e = (redisLibevEvents*)privdata;
+    struct ev_loop *loop = e->loop;
+    ((void)loop);
+    if (e->reading) {
+        e->reading = 0;
+        ev_io_stop(EV_A_ &e->rev);
+    }
+}
+
+static void redisLibevAddWrite(void *privdata) {
+    redisLibevEvents *e = (redisLibevEvents*)privdata;
+    struct ev_loop *loop = e->loop;
+    ((void)loop);
+    if (!e->writing) {
+        e->writing = 1;
+        ev_io_start(EV_A_ &e->wev);
+    }
+}
+
+static void redisLibevDelWrite(void *privdata) {
+    redisLibevEvents *e = (redisLibevEvents*)privdata;
+    struct ev_loop *loop = e->loop;
+    ((void)loop);
+    if (e->writing) {
+        e->writing = 0;
+        ev_io_stop(EV_A_ &e->wev);
+    }
+}
+
+static void redisLibevStopTimer(void *privdata) {
+    redisLibevEvents *e = (redisLibevEvents*)privdata;
+    struct ev_loop *loop = e->loop;
+    ((void)loop);
+    ev_timer_stop(EV_A_ &e->timer);
+}
+
+static void redisLibevCleanup(void *privdata) {
+    redisLibevEvents *e = (redisLibevEvents*)privdata;
+    redisLibevDelRead(privdata);
+    redisLibevDelWrite(privdata);
+    redisLibevStopTimer(privdata);
+    hi_free(e);
+}
+
+static void redisLibevTimeout(EV_P_ ev_timer *timer, int revents) {
+    ((void)revents);
+    redisLibevEvents *e = (redisLibevEvents*)timer->data;
+    redisAsyncHandleTimeout(e->context);
+}
+
+static void redisLibevSetTimeout(void *privdata, struct timeval tv) {
+    redisLibevEvents *e = (redisLibevEvents*)privdata;
+    struct ev_loop *loop = e->loop;
+    ((void)loop);
+
+    if (!ev_is_active(&e->timer)) {
+        ev_init(&e->timer, redisLibevTimeout);
+        e->timer.data = e;
+    }
+
+    e->timer.repeat = tv.tv_sec + tv.tv_usec / 1000000.00;
+    ev_timer_again(EV_A_ &e->timer);
+}
+
+static int redisLibevAttach(EV_P_ redisAsyncContext *ac) {
+    redisContext *c = &(ac->c);
+    redisLibevEvents *e;
+
+    /* Nothing should be attached when something is already attached */
+    if (ac->ev.data != NULL)
+        return REDIS_ERR;
+
+    /* Create container for context and r/w events */
+    e = (redisLibevEvents*)hi_calloc(1, sizeof(*e));
+    if (e == NULL)
+        return REDIS_ERR;
+
+    e->context = ac;
+#if EV_MULTIPLICITY
+    e->loop = loop;
+#else
+    e->loop = NULL;
+#endif
+    e->rev.data = e;
+    e->wev.data = e;
+
+    /* Register functions to start/stop listening for events */
+    ac->ev.addRead = redisLibevAddRead;
+    ac->ev.delRead = redisLibevDelRead;
+    ac->ev.addWrite = redisLibevAddWrite;
+    ac->ev.delWrite = redisLibevDelWrite;
+    ac->ev.cleanup = redisLibevCleanup;
+    ac->ev.scheduleTimer = redisLibevSetTimeout;
+    ac->ev.data = e;
+
+    /* Initialize read/write events */
+    ev_io_init(&e->rev,redisLibevReadEvent,c->fd,EV_READ);
+    ev_io_init(&e->wev,redisLibevWriteEvent,c->fd,EV_WRITE);
+    return REDIS_OK;
+}
+
+#endif
diff --git a/tools/msys/mingw32/include/hiredis/adapters/libevent.h b/tools/msys/mingw32/include/hiredis/adapters/libevent.h
new file mode 100644
index 0000000000000000000000000000000000000000..9150979bc6c55b417458f57fcae156c860823a45
--- /dev/null
+++ b/tools/msys/mingw32/include/hiredis/adapters/libevent.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of Redis nor the names of its contributors may be used
+ *     to endorse or promote products derived from this software without
+ *     specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __HIREDIS_LIBEVENT_H__
+#define __HIREDIS_LIBEVENT_H__
+#include <event2/event.h>
+#include "../hiredis.h"
+#include "../async.h"
+
+#define REDIS_LIBEVENT_DELETED 0x01
+#define REDIS_LIBEVENT_ENTERED 0x02
+
+typedef struct redisLibeventEvents {
+    redisAsyncContext *context;
+    struct event *ev;
+    struct event_base *base;
+    struct timeval tv;
+    short flags;
+    short state;
+} redisLibeventEvents;
+
+static void redisLibeventDestroy(redisLibeventEvents *e) {
+    hi_free(e);
+}
+
+static void redisLibeventHandler(int fd, short event, void *arg) {
+    ((void)fd);
+    redisLibeventEvents *e = (redisLibeventEvents*)arg;
+    e->state |= REDIS_LIBEVENT_ENTERED;
+
+    #define CHECK_DELETED() if (e->state & REDIS_LIBEVENT_DELETED) {\
+        redisLibeventDestroy(e);\
+        return; \
+    }
+
+    if ((event & EV_TIMEOUT) && (e->state & REDIS_LIBEVENT_DELETED) == 0) {
+        redisAsyncHandleTimeout(e->context);
+        CHECK_DELETED();
+    }
+
+    if ((event & EV_READ) && e->context && (e->state & REDIS_LIBEVENT_DELETED) == 0) {
+        redisAsyncHandleRead(e->context);
+        CHECK_DELETED();
+    }
+
+    if ((event & EV_WRITE) && e->context && (e->state & REDIS_LIBEVENT_DELETED) == 0) {
+        redisAsyncHandleWrite(e->context);
+        CHECK_DELETED();
+    }
+
+    e->state &= ~REDIS_LIBEVENT_ENTERED;
+    #undef CHECK_DELETED
+}
+
+static void redisLibeventUpdate(void *privdata, short flag, int isRemove) {
+    redisLibeventEvents *e = (redisLibeventEvents *)privdata;
+    const struct timeval *tv = e->tv.tv_sec || e->tv.tv_usec ? &e->tv : NULL;
+
+    if (isRemove) {
+        if ((e->flags & flag) == 0) {
+            return;
+        } else {
+            e->flags &= ~flag;
+        }
+    } else {
+        if (e->flags & flag) {
+            return;
+        } else {
+            e->flags |= flag;
+        }
+    }
+
+    event_del(e->ev);
+    event_assign(e->ev, e->base, e->context->c.fd, e->flags | EV_PERSIST,
+                 redisLibeventHandler, privdata);
+    event_add(e->ev, tv);
+}
+
+static void redisLibeventAddRead(void *privdata) {
+    redisLibeventUpdate(privdata, EV_READ, 0);
+}
+
+static void redisLibeventDelRead(void *privdata) {
+    redisLibeventUpdate(privdata, EV_READ, 1);
+}
+
+static void redisLibeventAddWrite(void *privdata) {
+    redisLibeventUpdate(privdata, EV_WRITE, 0);
+}
+
+static void redisLibeventDelWrite(void *privdata) {
+    redisLibeventUpdate(privdata, EV_WRITE, 1);
+}
+
+static void redisLibeventCleanup(void *privdata) {
+    redisLibeventEvents *e = (redisLibeventEvents*)privdata;
+    if (!e) {
+        return;
+    }
+    event_del(e->ev);
+    event_free(e->ev);
+    e->ev = NULL;
+
+    if (e->state & REDIS_LIBEVENT_ENTERED) {
+        e->state |= REDIS_LIBEVENT_DELETED;
+    } else {
+        redisLibeventDestroy(e);
+    }
+}
+
+static void redisLibeventSetTimeout(void *privdata, struct timeval tv) {
+    redisLibeventEvents *e = (redisLibeventEvents *)privdata;
+    short flags = e->flags;
+    e->flags = 0;
+    e->tv = tv;
+    redisLibeventUpdate(e, flags, 0);
+}
+
+static int redisLibeventAttach(redisAsyncContext *ac, struct event_base *base) {
+    redisContext *c = &(ac->c);
+    redisLibeventEvents *e;
+
+    /* Nothing should be attached when something is already attached */
+    if (ac->ev.data != NULL)
+        return REDIS_ERR;
+
+    /* Create container for context and r/w events */
+    e = (redisLibeventEvents*)hi_calloc(1, sizeof(*e));
+    if (e == NULL)
+        return REDIS_ERR;
+
+    e->context = ac;
+
+    /* Register functions to start/stop listening for events */
+    ac->ev.addRead = redisLibeventAddRead;
+    ac->ev.delRead = redisLibeventDelRead;
+    ac->ev.addWrite = redisLibeventAddWrite;
+    ac->ev.delWrite = redisLibeventDelWrite;
+    ac->ev.cleanup = redisLibeventCleanup;
+    ac->ev.scheduleTimer = redisLibeventSetTimeout;
+    ac->ev.data = e;
+
+    /* Initialize and install read/write events */
+    e->ev = event_new(base, c->fd, EV_READ | EV_WRITE, redisLibeventHandler, e);
+    e->base = base;
+    return REDIS_OK;
+}
+#endif
diff --git a/tools/msys/mingw32/include/hiredis/adapters/libuv.h b/tools/msys/mingw32/include/hiredis/adapters/libuv.h
new file mode 100644
index 0000000000000000000000000000000000000000..c120b1b396bc10270a39d08d9bb78d0e63c81baa
--- /dev/null
+++ b/tools/msys/mingw32/include/hiredis/adapters/libuv.h
@@ -0,0 +1,117 @@
+#ifndef __HIREDIS_LIBUV_H__
+#define __HIREDIS_LIBUV_H__
+#include <stdlib.h>
+#include <uv.h>
+#include "../hiredis.h"
+#include "../async.h"
+#include <string.h>
+
+typedef struct redisLibuvEvents {
+  redisAsyncContext* context;
+  uv_poll_t          handle;
+  int                events;
+} redisLibuvEvents;
+
+
+static void redisLibuvPoll(uv_poll_t* handle, int status, int events) {
+  redisLibuvEvents* p = (redisLibuvEvents*)handle->data;
+  int ev = (status ? p->events : events);
+
+  if (p->context != NULL && (ev & UV_READABLE)) {
+    redisAsyncHandleRead(p->context);
+  }
+  if (p->context != NULL && (ev & UV_WRITABLE)) {
+    redisAsyncHandleWrite(p->context);
+  }
+}
+
+
+static void redisLibuvAddRead(void *privdata) {
+  redisLibuvEvents* p = (redisLibuvEvents*)privdata;
+
+  p->events |= UV_READABLE;
+
+  uv_poll_start(&p->handle, p->events, redisLibuvPoll);
+}
+
+
+static void redisLibuvDelRead(void *privdata) {
+  redisLibuvEvents* p = (redisLibuvEvents*)privdata;
+
+  p->events &= ~UV_READABLE;
+
+  if (p->events) {
+    uv_poll_start(&p->handle, p->events, redisLibuvPoll);
+  } else {
+    uv_poll_stop(&p->handle);
+  }
+}
+
+
+static void redisLibuvAddWrite(void *privdata) {
+  redisLibuvEvents* p = (redisLibuvEvents*)privdata;
+
+  p->events |= UV_WRITABLE;
+
+  uv_poll_start(&p->handle, p->events, redisLibuvPoll);
+}
+
+
+static void redisLibuvDelWrite(void *privdata) {
+  redisLibuvEvents* p = (redisLibuvEvents*)privdata;
+
+  p->events &= ~UV_WRITABLE;
+
+  if (p->events) {
+    uv_poll_start(&p->handle, p->events, redisLibuvPoll);
+  } else {
+    uv_poll_stop(&p->handle);
+  }
+}
+
+
+static void on_close(uv_handle_t* handle) {
+  redisLibuvEvents* p = (redisLibuvEvents*)handle->data;
+
+  hi_free(p);
+}
+
+
+static void redisLibuvCleanup(void *privdata) {
+  redisLibuvEvents* p = (redisLibuvEvents*)privdata;
+
+  p->context = NULL; // indicate that context might no longer exist
+  uv_close((uv_handle_t*)&p->handle, on_close);
+}
+
+
+static int redisLibuvAttach(redisAsyncContext* ac, uv_loop_t* loop) {
+  redisContext *c = &(ac->c);
+
+  if (ac->ev.data != NULL) {
+    return REDIS_ERR;
+  }
+
+  ac->ev.addRead  = redisLibuvAddRead;
+  ac->ev.delRead  = redisLibuvDelRead;
+  ac->ev.addWrite = redisLibuvAddWrite;
+  ac->ev.delWrite = redisLibuvDelWrite;
+  ac->ev.cleanup  = redisLibuvCleanup;
+
+  redisLibuvEvents* p = (redisLibuvEvents*)hi_malloc(sizeof(*p));
+  if (p == NULL)
+      return REDIS_ERR;
+
+  memset(p, 0, sizeof(*p));
+
+  if (uv_poll_init_socket(loop, &p->handle, c->fd) != 0) {
+    return REDIS_ERR;
+  }
+
+  ac->ev.data    = p;
+  p->handle.data = p;
+  p->context     = ac;
+
+  return REDIS_OK;
+}
+#endif
diff --git a/tools/msys/mingw32/include/hiredis/adapters/macosx.h b/tools/msys/mingw32/include/hiredis/adapters/macosx.h
new file mode 100644
index 0000000000000000000000000000000000000000..3c87f1b2faafafcdae4b857003dd43dcf53e63be
--- /dev/null
+++ b/tools/msys/mingw32/include/hiredis/adapters/macosx.h
@@ -0,0 +1,115 @@
+//
+//  Created by Дмитрий Бахвалов on 13.07.15.
+//  Copyright (c) 2015 Dmitry Bakhvalov. All rights reserved.
+//
+
+#ifndef __HIREDIS_MACOSX_H__
+#define __HIREDIS_MACOSX_H__
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include "../hiredis.h"
+#include "../async.h"
+
+typedef struct {
+    redisAsyncContext *context;
+    CFSocketRef socketRef;
+    CFRunLoopSourceRef sourceRef;
+} RedisRunLoop;
+
+static int freeRedisRunLoop(RedisRunLoop* redisRunLoop) {
+    if( redisRunLoop != NULL ) {
+        if( redisRunLoop->sourceRef != NULL ) {
+            CFRunLoopSourceInvalidate(redisRunLoop->sourceRef);
+            CFRelease(redisRunLoop->sourceRef);
+        }
+        if( redisRunLoop->socketRef != NULL ) {
+            CFSocketInvalidate(redisRunLoop->socketRef);
+            CFRelease(redisRunLoop->socketRef);
+        }
+        hi_free(redisRunLoop);
+    }
+    return REDIS_ERR;
+}
+
+static void redisMacOSAddRead(void *privdata) {
+    RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
+    CFSocketEnableCallBacks(redisRunLoop->socketRef, kCFSocketReadCallBack);
+}
+
+static void redisMacOSDelRead(void *privdata) {
+    RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
+    CFSocketDisableCallBacks(redisRunLoop->socketRef, kCFSocketReadCallBack);
+}
+
+static void redisMacOSAddWrite(void *privdata) {
+    RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
+    CFSocketEnableCallBacks(redisRunLoop->socketRef, kCFSocketWriteCallBack);
+}
+
+static void redisMacOSDelWrite(void *privdata) {
+    RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
+    CFSocketDisableCallBacks(redisRunLoop->socketRef, kCFSocketWriteCallBack);
+}
+
+static void redisMacOSCleanup(void *privdata) {
+    RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
+    freeRedisRunLoop(redisRunLoop);
+}
+
+static void redisMacOSAsyncCallback(CFSocketRef __unused s, CFSocketCallBackType callbackType, CFDataRef __unused address, const void __unused *data, void *info) {
+    redisAsyncContext* context = (redisAsyncContext*) info;
+
+    switch (callbackType) {
+        case kCFSocketReadCallBack:
+            redisAsyncHandleRead(context);
+            break;
+
+        case kCFSocketWriteCallBack:
+            redisAsyncHandleWrite(context);
+            break;
+
+        default:
+            break;
+    }
+}
+
+static int redisMacOSAttach(redisAsyncContext *redisAsyncCtx, CFRunLoopRef runLoop) {
+    redisContext *redisCtx = &(redisAsyncCtx->c);
+
+    /* Nothing should be attached when something is already attached */
+    if( redisAsyncCtx->ev.data != NULL ) return REDIS_ERR;
+
+    RedisRunLoop* redisRunLoop = (RedisRunLoop*) hi_calloc(1, sizeof(RedisRunLoop));
+    if (redisRunLoop == NULL)
+        return REDIS_ERR;
+
+    /* Setup redis stuff */
+    redisRunLoop->context = redisAsyncCtx;
+
+    redisAsyncCtx->ev.addRead  = redisMacOSAddRead;
+    redisAsyncCtx->ev.delRead  = redisMacOSDelRead;
+    redisAsyncCtx->ev.addWrite = redisMacOSAddWrite;
+    redisAsyncCtx->ev.delWrite = redisMacOSDelWrite;
+    redisAsyncCtx->ev.cleanup  = redisMacOSCleanup;
+    redisAsyncCtx->ev.data     = redisRunLoop;
+
+    /* Initialize and install read/write events */
+    CFSocketContext socketCtx = { 0, redisAsyncCtx, NULL, NULL, NULL };
+
+    redisRunLoop->socketRef = CFSocketCreateWithNative(NULL, redisCtx->fd,
+                                                       kCFSocketReadCallBack | kCFSocketWriteCallBack,
+                                                       redisMacOSAsyncCallback,
+                                                       &socketCtx);
+    if( !redisRunLoop->socketRef ) return freeRedisRunLoop(redisRunLoop);
+
+    redisRunLoop->sourceRef = CFSocketCreateRunLoopSource(NULL, redisRunLoop->socketRef, 0);
+    if( !redisRunLoop->sourceRef ) return freeRedisRunLoop(redisRunLoop);
+
+    CFRunLoopAddSource(runLoop, redisRunLoop->sourceRef, kCFRunLoopDefaultMode);
+
+    return REDIS_OK;
+}
+
+#endif
+
diff --git a/tools/msys/mingw32/include/hiredis/adapters/qt.h b/tools/msys/mingw32/include/hiredis/adapters/qt.h
new file mode 100644
index 0000000000000000000000000000000000000000..5cc02e6ce5ee9bda81344fba5214db17d30cf307
--- /dev/null
+++ b/tools/msys/mingw32/include/hiredis/adapters/qt.h
@@ -0,0 +1,135 @@
+/*-
+ * Copyright (C) 2014 Pietro Cerutti <gahr@gahr.ch>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __HIREDIS_QT_H__
+#define __HIREDIS_QT_H__
+#include <QSocketNotifier>
+#include "../async.h"
+
+static void RedisQtAddRead(void *);
+static void RedisQtDelRead(void *);
+static void RedisQtAddWrite(void *);
+static void RedisQtDelWrite(void *);
+static void RedisQtCleanup(void *);
+
+class RedisQtAdapter : public QObject {
+
+    Q_OBJECT
+
+    friend
+    void RedisQtAddRead(void * adapter) {
+        RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter);
+        a->addRead();
+    }
+
+    friend
+    void RedisQtDelRead(void * adapter) {
+        RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter);
+        a->delRead();
+    }
+
+    friend
+    void RedisQtAddWrite(void * adapter) {
+        RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter);
+        a->addWrite();
+    }
+
+    friend
+    void RedisQtDelWrite(void * adapter) {
+        RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter);
+        a->delWrite();
+    }
+
+    friend
+    void RedisQtCleanup(void * adapter) {
+        RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter);
+        a->cleanup();
+    }
+
+    public:
+        RedisQtAdapter(QObject * parent = 0)
+            : QObject(parent), m_ctx(0), m_read(0), m_write(0) { }
+
+        ~RedisQtAdapter() {
+            if (m_ctx != 0) {
+                m_ctx->ev.data = NULL;
+            }
+        }
+
+        int setContext(redisAsyncContext * ac) {
+            if (ac->ev.data != NULL) {
+                return REDIS_ERR;
+            }
+            m_ctx = ac;
+            m_ctx->ev.data = this;
+            m_ctx->ev.addRead = RedisQtAddRead;
+            m_ctx->ev.delRead = RedisQtDelRead;
+            m_ctx->ev.addWrite = RedisQtAddWrite;
+            m_ctx->ev.delWrite = RedisQtDelWrite;
+            m_ctx->ev.cleanup = RedisQtCleanup;
+            return REDIS_OK;
+        }
+
+    private:
+        void addRead() {
+            if (m_read) return;
+            m_read = new QSocketNotifier(m_ctx->c.fd, QSocketNotifier::Read, 0);
+            connect(m_read, SIGNAL(activated(int)), this, SLOT(read()));
+        }
+
+        void delRead() {
+            if (!m_read) return;
+            delete m_read;
+            m_read = 0;
+        }
+
+        void addWrite() {
+            if (m_write) return;
+            m_write = new QSocketNotifier(m_ctx->c.fd, QSocketNotifier::Write, 0);
+            connect(m_write, SIGNAL(activated(int)), this, SLOT(write()));
+        }
+
+        void delWrite() {
+            if (!m_write) return;
+            delete m_write;
+            m_write = 0;
+        }
+
+        void cleanup() {
+            delRead();
+            delWrite();
+        }
+
+    private slots:
+        void read() { redisAsyncHandleRead(m_ctx); }
+        void write() { redisAsyncHandleWrite(m_ctx); }
+
+    private:
+        redisAsyncContext * m_ctx;
+        QSocketNotifier * m_read;
+        QSocketNotifier * m_write;
+};
+
+#endif /* !__HIREDIS_QT_H__ */
diff --git a/tools/msys/mingw32/include/hiredis/alloc.h b/tools/msys/mingw32/include/hiredis/alloc.h
new file mode 100644
index 0000000000000000000000000000000000000000..34a05f49f3161e345292ca59e5dfd0ff8b2f4937
--- /dev/null
+++ b/tools/msys/mingw32/include/hiredis/alloc.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2020, Michael Grunder <michael dot grunder at gmail dot com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of Redis nor the names of its contributors may be used
+ *     to endorse or promote products derived from this software without
+ *     specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HIREDIS_ALLOC_H
+#define HIREDIS_ALLOC_H
+
+#include <stddef.h> /* for size_t */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Structure pointing to our actually configured allocators */
+typedef struct hiredisAllocFuncs {
+    void *(*mallocFn)(size_t);
+    void *(*callocFn)(size_t,size_t);
+    void *(*reallocFn)(void*,size_t);
+    char *(*strdupFn)(const char*);
+    void (*freeFn)(void*);
+} hiredisAllocFuncs;
+
+hiredisAllocFuncs hiredisSetAllocators(hiredisAllocFuncs *ha);
+void hiredisResetAllocators(void);
+
+#ifndef _WIN32
+
+/* Hiredis' configured allocator function pointer struct */
+extern hiredisAllocFuncs hiredisAllocFns;
+
+static inline void *hi_malloc(size_t size) {
+    return hiredisAllocFns.mallocFn(size);
+}
+
+static inline void *hi_calloc(size_t nmemb, size_t size) {
+    return hiredisAllocFns.callocFn(nmemb, size);
+}
+
+static inline void *hi_realloc(void *ptr, size_t size) {
+    return hiredisAllocFns.reallocFn(ptr, size);
+}
+
+static inline char *hi_strdup(const char *str) {
+    return hiredisAllocFns.strdupFn(str);
+}
+
+static inline void hi_free(void *ptr) {
+    hiredisAllocFns.freeFn(ptr);
+}
+
+#else
+
+void *hi_malloc(size_t size);
+void *hi_calloc(size_t nmemb, size_t size);
+void *hi_realloc(void *ptr, size_t size);
+char *hi_strdup(const char *str);
+void hi_free(void *ptr);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HIREDIS_ALLOC_H */
diff --git a/tools/msys/mingw32/include/hiredis/async.h b/tools/msys/mingw32/include/hiredis/async.h
new file mode 100644
index 0000000000000000000000000000000000000000..b1d2cb263f9979db8416c966432e35c39909379b
--- /dev/null
+++ b/tools/msys/mingw32/include/hiredis/async.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
+ * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of Redis nor the names of its contributors may be used
+ *     to endorse or promote products derived from this software without
+ *     specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __HIREDIS_ASYNC_H
+#define __HIREDIS_ASYNC_H
+#include "hiredis.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct redisAsyncContext; /* need forward declaration of redisAsyncContext */
+struct dict; /* dictionary header is included in async.c */
+
+/* Reply callback prototype and container */
+typedef void (redisCallbackFn)(struct redisAsyncContext*, void*, void*);
+typedef struct redisCallback {
+    struct redisCallback *next; /* simple singly linked list */
+    redisCallbackFn *fn;
+    int pending_subs;
+    void *privdata;
+} redisCallback;
+
+/* List of callbacks for either regular replies or pub/sub */
+typedef struct redisCallbackList {
+    redisCallback *head, *tail;
+} redisCallbackList;
+
+/* Connection callback prototypes */
+typedef void (redisDisconnectCallback)(const struct redisAsyncContext*, int status);
+typedef void (redisConnectCallback)(const struct redisAsyncContext*, int status);
+typedef void(redisTimerCallback)(void *timer, void *privdata);
+
+/* Context for an async connection to Redis */
+typedef struct redisAsyncContext {
+    /* Hold the regular context, so it can be realloc'ed. */
+    redisContext c;
+
+    /* Setup error flags so they can be used directly. */
+    int err;
+    char *errstr;
+
+    /* Not used by hiredis */
+    void *data;
+    void (*dataCleanup)(void *privdata);
+
+    /* Event library data and hooks */
+    struct {
+        void *data;
+
+        /* Hooks that are called when the library expects to start
+         * reading/writing. These functions should be idempotent. */
+        void (*addRead)(void *privdata);
+        void (*delRead)(void *privdata);
+        void (*addWrite)(void *privdata);
+        void (*delWrite)(void *privdata);
+        void (*cleanup)(void *privdata);
+        void (*scheduleTimer)(void *privdata, struct timeval tv);
+    } ev;
+
+    /* Called when either the connection is terminated due to an error or per
+     * user request. The status is set accordingly (REDIS_OK, REDIS_ERR). */
+    redisDisconnectCallback *onDisconnect;
+
+    /* Called when the first write event was received. */
+    redisConnectCallback *onConnect;
+
+    /* Regular command callbacks */
+    redisCallbackList replies;
+
+    /* Address used for connect() */
+    struct sockaddr *saddr;
+    size_t addrlen;
+
+    /* Subscription callbacks */
+    struct {
+        redisCallbackList invalid;
+        struct dict *channels;
+        struct dict *patterns;
+    } sub;
+
+    /* Any configured RESP3 PUSH handler */
+    redisAsyncPushFn *push_cb;
+} redisAsyncContext;
+
+/* Functions that proxy to hiredis */
+redisAsyncContext *redisAsyncConnectWithOptions(const redisOptions *options);
+redisAsyncContext *redisAsyncConnect(const char *ip, int port);
+redisAsyncContext *redisAsyncConnectBind(const char *ip, int port, const char *source_addr);
+redisAsyncContext *redisAsyncConnectBindWithReuse(const char *ip, int port,
+                                                  const char *source_addr);
+redisAsyncContext *redisAsyncConnectUnix(const char *path);
+int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn);
+int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn);
+
+redisAsyncPushFn *redisAsyncSetPushCallback(redisAsyncContext *ac, redisAsyncPushFn *fn);
+int redisAsyncSetTimeout(redisAsyncContext *ac, struct timeval tv);
+void redisAsyncDisconnect(redisAsyncContext *ac);
+void redisAsyncFree(redisAsyncContext *ac);
+
+/* Handle read/write events */
+void redisAsyncHandleRead(redisAsyncContext *ac);
+void redisAsyncHandleWrite(redisAsyncContext *ac);
+void redisAsyncHandleTimeout(redisAsyncContext *ac);
+void redisAsyncRead(redisAsyncContext *ac);
+void redisAsyncWrite(redisAsyncContext *ac);
+
+/* Command functions for an async context. Write the command to the
+ * output buffer and register the provided callback. */
+int redisvAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, va_list ap);
+int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, ...);
+int redisAsyncCommandArgv(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen);
+int redisAsyncFormattedCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/tools/msys/mingw32/include/hiredis/hiredis.h b/tools/msys/mingw32/include/hiredis/hiredis.h
new file mode 100644
index 0000000000000000000000000000000000000000..0622aaab8d60b02f8ef64f3062d30f99b1a6b3ff
--- /dev/null
+++ b/tools/msys/mingw32/include/hiredis/hiredis.h
@@ -0,0 +1,336 @@
+/*
+ * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
+ * Copyright (c) 2010-2014, Pieter Noordhuis <pcnoordhuis at gmail dot com>
+ * Copyright (c) 2015, Matt Stancliff <matt at genges dot com>,
+ *                     Jan-Erik Rediger <janerik at fnordig dot com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of Redis nor the names of its contributors may be used
+ *     to endorse or promote products derived from this software without
+ *     specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __HIREDIS_H
+#define __HIREDIS_H
+#include "read.h"
+#include <stdarg.h> /* for va_list */
+#ifndef _MSC_VER
+#include <sys/time.h> /* for struct timeval */
+#else
+struct timeval; /* forward declaration */
+typedef long long ssize_t;
+#endif
+#include <stdint.h> /* uintXX_t, etc */
+#include "sds.h" /* for sds */
+#include "alloc.h" /* for allocation wrappers */
+
+#define HIREDIS_MAJOR 1
+#define HIREDIS_MINOR 0
+#define HIREDIS_PATCH 0
+#define HIREDIS_SONAME 1.0.0
+
+/* Connection type can be blocking or non-blocking and is set in the
+ * least significant bit of the flags field in redisContext. */
+#define REDIS_BLOCK 0x1
+
+/* Connection may be disconnected before being free'd. The second bit
+ * in the flags field is set when the context is connected. */
+#define REDIS_CONNECTED 0x2
+
+/* The async API might try to disconnect cleanly and flush the output
+ * buffer and read all subsequent replies before disconnecting.
+ * This flag means no new commands can come in and the connection
+ * should be terminated once all replies have been read. */
+#define REDIS_DISCONNECTING 0x4
+
+/* Flag specific to the async API which means that the context should be clean
+ * up as soon as possible. */
+#define REDIS_FREEING 0x8
+
+/* Flag that is set when an async callback is executed. */
+#define REDIS_IN_CALLBACK 0x10
+
+/* Flag that is set when the async context has one or more subscriptions. */
+#define REDIS_SUBSCRIBED 0x20
+
+/* Flag that is set when monitor mode is active */
+#define REDIS_MONITORING 0x40
+
+/* Flag that is set when we should set SO_REUSEADDR before calling bind() */
+#define REDIS_REUSEADDR 0x80
+
+/**
+ * Flag that indicates the user does not want the context to
+ * be automatically freed upon error
+ */
+#define REDIS_NO_AUTO_FREE 0x200
+
+#define REDIS_KEEPALIVE_INTERVAL 15 /* seconds */
+
+/* number of times we retry to connect in the case of EADDRNOTAVAIL and
+ * SO_REUSEADDR is being used. */
+#define REDIS_CONNECT_RETRIES  10
+
+/* Forward declarations for structs defined elsewhere */
+struct redisAsyncContext;
+struct redisContext;
+
+/* RESP3 push helpers and callback prototypes */
+#define redisIsPushReply(r) (((redisReply*)(r))->type == REDIS_REPLY_PUSH)
+typedef void (redisPushFn)(void *, void *);
+typedef void (redisAsyncPushFn)(struct redisAsyncContext *, void *);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* This is the reply object returned by redisCommand() */
+typedef struct redisReply {
+    int type; /* REDIS_REPLY_* */
+    long long integer; /* The integer when type is REDIS_REPLY_INTEGER */
+    double dval; /* The double when type is REDIS_REPLY_DOUBLE */
+    size_t len; /* Length of string */
+    char *str; /* Used for REDIS_REPLY_ERROR, REDIS_REPLY_STRING
+                  REDIS_REPLY_VERB, and REDIS_REPLY_DOUBLE (in additional to dval). */
+    char vtype[4]; /* Used for REDIS_REPLY_VERB, contains the null
+                      terminated 3 character content type, such as "txt". */
+    size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */
+    struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */
+} redisReply;
+
+redisReader *redisReaderCreate(void);
+
+/* Function to free the reply objects hiredis returns by default. */
+void freeReplyObject(void *reply);
+
+/* Functions to format a command according to the protocol. */
+int redisvFormatCommand(char **target, const char *format, va_list ap);
+int redisFormatCommand(char **target, const char *format, ...);
+int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen);
+int redisFormatSdsCommandArgv(sds *target, int argc, const char ** argv, const size_t *argvlen);
+void redisFreeCommand(char *cmd);
+void redisFreeSdsCommand(sds cmd);
+
+enum redisConnectionType {
+    REDIS_CONN_TCP,
+    REDIS_CONN_UNIX,
+    REDIS_CONN_USERFD
+};
+
+struct redisSsl;
+
+#define REDIS_OPT_NONBLOCK 0x01
+#define REDIS_OPT_REUSEADDR 0x02
+
+/**
+ * Don't automatically free the async object on a connection failure,
+ * or other implicit conditions. Only free on an explicit call to disconnect() or free()
+ */
+#define REDIS_OPT_NOAUTOFREE 0x04
+
+/* Don't automatically intercept and free RESP3 PUSH replies. */
+#define REDIS_OPT_NO_PUSH_AUTOFREE 0x08
+
+/* In Unix systems a file descriptor is a regular signed int, with -1
+ * representing an invalid descriptor. In Windows it is a SOCKET
+ * (32- or 64-bit unsigned integer depending on the architecture), where
+ * all bits set (~0) is INVALID_SOCKET.  */
+#ifndef _WIN32
+typedef int redisFD;
+#define REDIS_INVALID_FD -1
+#else
+#ifdef _WIN64
+typedef unsigned long long redisFD; /* SOCKET = 64-bit UINT_PTR */
+#else
+typedef unsigned long redisFD;      /* SOCKET = 32-bit UINT_PTR */
+#endif
+#define REDIS_INVALID_FD ((redisFD)(~0)) /* INVALID_SOCKET */
+#endif
+
+typedef struct {
+    /*
+     * the type of connection to use. This also indicates which
+     * `endpoint` member field to use
+     */
+    int type;
+    /* bit field of REDIS_OPT_xxx */
+    int options;
+    /* timeout value for connect operation. If NULL, no timeout is used */
+    const struct timeval *connect_timeout;
+    /* timeout value for commands. If NULL, no timeout is used.  This can be
+     * updated at runtime with redisSetTimeout/redisAsyncSetTimeout. */
+    const struct timeval *command_timeout;
+    union {
+        /** use this field for tcp/ip connections */
+        struct {
+            const char *source_addr;
+            const char *ip;
+            int port;
+        } tcp;
+        /** use this field for unix domain sockets */
+        const char *unix_socket;
+        /**
+         * use this field to have hiredis operate an already-open
+         * file descriptor */
+        redisFD fd;
+    } endpoint;
+
+    /* Optional user defined data/destructor */
+    void *privdata;
+    void (*free_privdata)(void *);
+
+    /* A user defined PUSH message callback */
+    redisPushFn *push_cb;
+    redisAsyncPushFn *async_push_cb;
+} redisOptions;
+
+/**
+ * Helper macros to initialize options to their specified fields.
+ */
+#define REDIS_OPTIONS_SET_TCP(opts, ip_, port_) \
+    (opts)->type = REDIS_CONN_TCP; \
+    (opts)->endpoint.tcp.ip = ip_; \
+    (opts)->endpoint.tcp.port = port_;
+
+#define REDIS_OPTIONS_SET_UNIX(opts, path) \
+    (opts)->type = REDIS_CONN_UNIX;        \
+    (opts)->endpoint.unix_socket = path;
+
+#define REDIS_OPTIONS_SET_PRIVDATA(opts, data, dtor) \
+    (opts)->privdata = data;                         \
+    (opts)->free_privdata = dtor;                    \
+
+typedef struct redisContextFuncs {
+    void (*free_privctx)(void *);
+    void (*async_read)(struct redisAsyncContext *);
+    void (*async_write)(struct redisAsyncContext *);
+    ssize_t (*read)(struct redisContext *, char *, size_t);
+    ssize_t (*write)(struct redisContext *);
+} redisContextFuncs;
+
+/* Context for a connection to Redis */
+typedef struct redisContext {
+    const redisContextFuncs *funcs;   /* Function table */
+
+    int err; /* Error flags, 0 when there is no error */
+    char errstr[128]; /* String representation of error when applicable */
+    redisFD fd;
+    int flags;
+    char *obuf; /* Write buffer */
+    redisReader *reader; /* Protocol reader */
+
+    enum redisConnectionType connection_type;
+    struct timeval *connect_timeout;
+    struct timeval *command_timeout;
+
+    struct {
+        char *host;
+        char *source_addr;
+        int port;
+    } tcp;
+
+    struct {
+        char *path;
+    } unix_sock;
+
+    /* For non-blocking connect */
+    struct sockadr *saddr;
+    size_t addrlen;
+
+    /* Optional data and corresponding destructor users can use to provide
+     * context to a given redisContext.  Not used by hiredis. */
+    void *privdata;
+    void (*free_privdata)(void *);
+
+    /* Internal context pointer presently used by hiredis to manage
+     * SSL connections. */
+    void *privctx;
+
+    /* An optional RESP3 PUSH handler */
+    redisPushFn *push_cb;
+} redisContext;
+
+redisContext *redisConnectWithOptions(const redisOptions *options);
+redisContext *redisConnect(const char *ip, int port);
+redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv);
+redisContext *redisConnectNonBlock(const char *ip, int port);
+redisContext *redisConnectBindNonBlock(const char *ip, int port,
+                                       const char *source_addr);
+redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port,
+                                                const char *source_addr);
+redisContext *redisConnectUnix(const char *path);
+redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv);
+redisContext *redisConnectUnixNonBlock(const char *path);
+redisContext *redisConnectFd(redisFD fd);
+
+/**
+ * Reconnect the given context using the saved information.
+ *
+ * This re-uses the exact same connect options as in the initial connection.
+ * host, ip (or path), timeout and bind address are reused,
+ * flags are used unmodified from the existing context.
+ *
+ * Returns REDIS_OK on successful connect or REDIS_ERR otherwise.
+ */
+int redisReconnect(redisContext *c);
+
+redisPushFn *redisSetPushCallback(redisContext *c, redisPushFn *fn);
+int redisSetTimeout(redisContext *c, const struct timeval tv);
+int redisEnableKeepAlive(redisContext *c);
+void redisFree(redisContext *c);
+redisFD redisFreeKeepFd(redisContext *c);
+int redisBufferRead(redisContext *c);
+int redisBufferWrite(redisContext *c, int *done);
+
+/* In a blocking context, this function first checks if there are unconsumed
+ * replies to return and returns one if so. Otherwise, it flushes the output
+ * buffer to the socket and reads until it has a reply. In a non-blocking
+ * context, it will return unconsumed replies until there are no more. */
+int redisGetReply(redisContext *c, void **reply);
+int redisGetReplyFromReader(redisContext *c, void **reply);
+
+/* Write a formatted command to the output buffer. Use these functions in blocking mode
+ * to get a pipeline of commands. */
+int redisAppendFormattedCommand(redisContext *c, const char *cmd, size_t len);
+
+/* Write a command to the output buffer. Use these functions in blocking mode
+ * to get a pipeline of commands. */
+int redisvAppendCommand(redisContext *c, const char *format, va_list ap);
+int redisAppendCommand(redisContext *c, const char *format, ...);
+int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
+
+/* Issue a command to Redis. In a blocking context, it is identical to calling
+ * redisAppendCommand, followed by redisGetReply. The function will return
+ * NULL if there was an error in performing the request, otherwise it will
+ * return the reply. In a non-blocking context, it is identical to calling
+ * only redisAppendCommand and will always return NULL. */
+void *redisvCommand(redisContext *c, const char *format, va_list ap);
+void *redisCommand(redisContext *c, const char *format, ...);
+void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/tools/msys/mingw32/include/hiredis/hiredis_ssl.h b/tools/msys/mingw32/include/hiredis/hiredis_ssl.h
new file mode 100644
index 0000000000000000000000000000000000000000..604efe0c10dd7d0c720db5c28dee15933a30252b
--- /dev/null
+++ b/tools/msys/mingw32/include/hiredis/hiredis_ssl.h
@@ -0,0 +1,127 @@
+
+/*
+ * Copyright (c) 2019, Redis Labs
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of Redis nor the names of its contributors may be used
+ *     to endorse or promote products derived from this software without
+ *     specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __HIREDIS_SSL_H
+#define __HIREDIS_SSL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* This is the underlying struct for SSL in ssl.h, which is not included to
+ * keep build dependencies short here.
+ */
+struct ssl_st;
+
+/* A wrapper around OpenSSL SSL_CTX to allow easy SSL use without directly
+ * calling OpenSSL.
+ */
+typedef struct redisSSLContext redisSSLContext;
+
+/**
+ * Initialization errors that redisCreateSSLContext() may return.
+ */
+
+typedef enum {
+    REDIS_SSL_CTX_NONE = 0,                     /* No Error */
+    REDIS_SSL_CTX_CREATE_FAILED,                /* Failed to create OpenSSL SSL_CTX */
+    REDIS_SSL_CTX_CERT_KEY_REQUIRED,            /* Client cert and key must both be specified or skipped */
+    REDIS_SSL_CTX_CA_CERT_LOAD_FAILED,          /* Failed to load CA Certificate or CA Path */
+    REDIS_SSL_CTX_CLIENT_CERT_LOAD_FAILED,      /* Failed to load client certificate */
+    REDIS_SSL_CTX_PRIVATE_KEY_LOAD_FAILED       /* Failed to load private key */
+} redisSSLContextError;
+
+/**
+ * Return the error message corresponding with the specified error code.
+ */
+
+const char *redisSSLContextGetError(redisSSLContextError error);
+
+/**
+ * Helper function to initialize the OpenSSL library.
+ *
+ * OpenSSL requires one-time initialization before it can be used. Callers should
+ * call this function only once, and only if OpenSSL is not directly initialized
+ * elsewhere.
+ */
+int redisInitOpenSSL(void);
+
+/**
+ * Helper function to initialize an OpenSSL context that can be used
+ * to initiate SSL connections.
+ *
+ * cacert_filename is an optional name of a CA certificate/bundle file to load
+ * and use for validation.
+ *
+ * capath is an optional directory path where trusted CA certificate files are
+ * stored in an OpenSSL-compatible structure.
+ *
+ * cert_filename and private_key_filename are optional names of a client side
+ * certificate and private key files to use for authentication. They need to
+ * be both specified or omitted.
+ *
+ * server_name is an optional and will be used as a server name indication
+ * (SNI) TLS extension.
+ *
+ * If error is non-null, it will be populated in case the context creation fails
+ * (returning a NULL).
+ */
+
+redisSSLContext *redisCreateSSLContext(const char *cacert_filename, const char *capath,
+        const char *cert_filename, const char *private_key_filename,
+        const char *server_name, redisSSLContextError *error);
+
+/**
+ * Free a previously created OpenSSL context.
+ */
+void redisFreeSSLContext(redisSSLContext *redis_ssl_ctx);
+
+/**
+ * Initiate SSL on an existing redisContext.
+ *
+ * This is similar to redisInitiateSSL() but does not require the caller
+ * to directly interact with OpenSSL, and instead uses a redisSSLContext
+ * previously created using redisCreateSSLContext().
+ */
+
+int redisInitiateSSLWithContext(redisContext *c, redisSSLContext *redis_ssl_ctx);
+
+/**
+ * Initiate SSL/TLS negotiation on a provided OpenSSL SSL object.
+ */
+
+int redisInitiateSSL(redisContext *c, struct ssl_st *ssl);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* __HIREDIS_SSL_H */
diff --git a/tools/msys/mingw32/include/hiredis/read.h b/tools/msys/mingw32/include/hiredis/read.h
new file mode 100644
index 0000000000000000000000000000000000000000..2d74d77a5b41d067537587f3a34565fed4bb1da3
--- /dev/null
+++ b/tools/msys/mingw32/include/hiredis/read.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
+ * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of Redis nor the names of its contributors may be used
+ *     to endorse or promote products derived from this software without
+ *     specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef __HIREDIS_READ_H
+#define __HIREDIS_READ_H
+#include <stdio.h> /* for size_t */
+
+#define REDIS_ERR -1
+#define REDIS_OK 0
+
+/* When an error occurs, the err flag in a context is set to hold the type of
+ * error that occurred. REDIS_ERR_IO means there was an I/O error and you
+ * should use the "errno" variable to find out what is wrong.
+ * For other values, the "errstr" field will hold a description. */
+#define REDIS_ERR_IO 1 /* Error in read or write */
+#define REDIS_ERR_EOF 3 /* End of file */
+#define REDIS_ERR_PROTOCOL 4 /* Protocol error */
+#define REDIS_ERR_OOM 5 /* Out of memory */
+#define REDIS_ERR_TIMEOUT 6 /* Timed out */
+#define REDIS_ERR_OTHER 2 /* Everything else... */
+
+#define REDIS_REPLY_STRING 1
+#define REDIS_REPLY_ARRAY 2
+#define REDIS_REPLY_INTEGER 3
+#define REDIS_REPLY_NIL 4
+#define REDIS_REPLY_STATUS 5
+#define REDIS_REPLY_ERROR 6
+#define REDIS_REPLY_DOUBLE 7
+#define REDIS_REPLY_BOOL 8
+#define REDIS_REPLY_MAP 9
+#define REDIS_REPLY_SET 10
+#define REDIS_REPLY_ATTR 11
+#define REDIS_REPLY_PUSH 12
+#define REDIS_REPLY_BIGNUM 13
+#define REDIS_REPLY_VERB 14
+
+/* Default max unused reader buffer. */
+#define REDIS_READER_MAX_BUF (1024*16)
+
+/* Default multi-bulk element limit */
+#define REDIS_READER_MAX_ARRAY_ELEMENTS ((1LL<<32) - 1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct redisReadTask {
+    int type;
+    long long elements; /* number of elements in multibulk container */
+    int idx; /* index in parent (array) object */
+    void *obj; /* holds user-generated value for a read task */
+    struct redisReadTask *parent; /* parent task */
+    void *privdata; /* user-settable arbitrary field */
+} redisReadTask;
+
+typedef struct redisReplyObjectFunctions {
+    void *(*createString)(const redisReadTask*, char*, size_t);
+    void *(*createArray)(const redisReadTask*, size_t);
+    void *(*createInteger)(const redisReadTask*, long long);
+    void *(*createDouble)(const redisReadTask*, double, char*, size_t);
+    void *(*createNil)(const redisReadTask*);
+    void *(*createBool)(const redisReadTask*, int);
+    void (*freeObject)(void*);
+} redisReplyObjectFunctions;
+
+typedef struct redisReader {
+    int err; /* Error flags, 0 when there is no error */
+    char errstr[128]; /* String representation of error when applicable */
+
+    char *buf; /* Read buffer */
+    size_t pos; /* Buffer cursor */
+    size_t len; /* Buffer length */
+    size_t maxbuf; /* Max length of unused buffer */
+    long long maxelements; /* Max multi-bulk elements */
+
+    redisReadTask **task;
+    int tasks;
+
+    int ridx; /* Index of current read task */
+    void *reply; /* Temporary reply pointer */
+
+    redisReplyObjectFunctions *fn;
+    void *privdata;
+} redisReader;
+
+/* Public API for the protocol parser. */
+redisReader *redisReaderCreateWithFunctions(redisReplyObjectFunctions *fn);
+void redisReaderFree(redisReader *r);
+int redisReaderFeed(redisReader *r, const char *buf, size_t len);
+int redisReaderGetReply(redisReader *r, void **reply);
+
+#define redisReaderSetPrivdata(_r, _p) (int)(((redisReader*)(_r))->privdata = (_p))
+#define redisReaderGetObject(_r) (((redisReader*)(_r))->reply)
+#define redisReaderGetError(_r) (((redisReader*)(_r))->errstr)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/tools/msys/mingw32/include/hiredis/sds.h b/tools/msys/mingw32/include/hiredis/sds.h
new file mode 100644
index 0000000000000000000000000000000000000000..eda8833b598e883e6db1d1a6382b65a48ce0999d
--- /dev/null
+++ b/tools/msys/mingw32/include/hiredis/sds.h
@@ -0,0 +1,278 @@
+/* SDSLib 2.0 -- A C dynamic strings library
+ *
+ * Copyright (c) 2006-2015, Salvatore Sanfilippo <antirez at gmail dot com>
+ * Copyright (c) 2015, Oran Agra
+ * Copyright (c) 2015, Redis Labs, Inc
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of Redis nor the names of its contributors may be used
+ *     to endorse or promote products derived from this software without
+ *     specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __SDS_H
+#define __SDS_H
+
+#define SDS_MAX_PREALLOC (1024*1024)
+#ifdef _MSC_VER
+#define __attribute__(x)
+typedef long long ssize_t;
+#define SSIZE_MAX (LLONG_MAX >> 1)
+#endif
+
+#include <sys/types.h>
+#include <stdarg.h>
+#include <stdint.h>
+
+typedef char *sds;
+
+/* Note: sdshdr5 is never used, we just access the flags byte directly.
+ * However is here to document the layout of type 5 SDS strings. */
+struct __attribute__ ((__packed__)) sdshdr5 {
+    unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
+    char buf[];
+};
+struct __attribute__ ((__packed__)) sdshdr8 {
+    uint8_t len; /* used */
+    uint8_t alloc; /* excluding the header and null terminator */
+    unsigned char flags; /* 3 lsb of type, 5 unused bits */
+    char buf[];
+};
+struct __attribute__ ((__packed__)) sdshdr16 {
+    uint16_t len; /* used */
+    uint16_t alloc; /* excluding the header and null terminator */
+    unsigned char flags; /* 3 lsb of type, 5 unused bits */
+    char buf[];
+};
+struct __attribute__ ((__packed__)) sdshdr32 {
+    uint32_t len; /* used */
+    uint32_t alloc; /* excluding the header and null terminator */
+    unsigned char flags; /* 3 lsb of type, 5 unused bits */
+    char buf[];
+};
+struct __attribute__ ((__packed__)) sdshdr64 {
+    uint64_t len; /* used */
+    uint64_t alloc; /* excluding the header and null terminator */
+    unsigned char flags; /* 3 lsb of type, 5 unused bits */
+    char buf[];
+};
+
+#define SDS_TYPE_5  0
+#define SDS_TYPE_8  1
+#define SDS_TYPE_16 2
+#define SDS_TYPE_32 3
+#define SDS_TYPE_64 4
+#define SDS_TYPE_MASK 7
+#define SDS_TYPE_BITS 3
+#define SDS_HDR_VAR(T,s) struct sdshdr##T *sh = (struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T)));
+#define SDS_HDR(T,s) ((struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T))))
+#define SDS_TYPE_5_LEN(f) ((f)>>SDS_TYPE_BITS)
+
+static inline size_t sdslen(const sds s) {
+    unsigned char flags = s[-1];
+    switch(flags&SDS_TYPE_MASK) {
+        case SDS_TYPE_5:
+            return SDS_TYPE_5_LEN(flags);
+        case SDS_TYPE_8:
+            return SDS_HDR(8,s)->len;
+        case SDS_TYPE_16:
+            return SDS_HDR(16,s)->len;
+        case SDS_TYPE_32:
+            return SDS_HDR(32,s)->len;
+        case SDS_TYPE_64:
+            return SDS_HDR(64,s)->len;
+    }
+    return 0;
+}
+
+static inline size_t sdsavail(const sds s) {
+    unsigned char flags = s[-1];
+    switch(flags&SDS_TYPE_MASK) {
+        case SDS_TYPE_5: {
+            return 0;
+        }
+        case SDS_TYPE_8: {
+            SDS_HDR_VAR(8,s);
+            return sh->alloc - sh->len;
+        }
+        case SDS_TYPE_16: {
+            SDS_HDR_VAR(16,s);
+            return sh->alloc - sh->len;
+        }
+        case SDS_TYPE_32: {
+            SDS_HDR_VAR(32,s);
+            return sh->alloc - sh->len;
+        }
+        case SDS_TYPE_64: {
+            SDS_HDR_VAR(64,s);
+            return sh->alloc - sh->len;
+        }
+    }
+    return 0;
+}
+
+static inline void sdssetlen(sds s, size_t newlen) {
+    unsigned char flags = s[-1];
+    switch(flags&SDS_TYPE_MASK) {
+        case SDS_TYPE_5:
+            {
+                unsigned char *fp = ((unsigned char*)s)-1;
+                *fp = (unsigned char)(SDS_TYPE_5 | (newlen << SDS_TYPE_BITS));
+            }
+            break;
+        case SDS_TYPE_8:
+            SDS_HDR(8,s)->len = (uint8_t)newlen;
+            break;
+        case SDS_TYPE_16:
+            SDS_HDR(16,s)->len = (uint16_t)newlen;
+            break;
+        case SDS_TYPE_32:
+            SDS_HDR(32,s)->len = (uint32_t)newlen;
+            break;
+        case SDS_TYPE_64:
+            SDS_HDR(64,s)->len = (uint64_t)newlen;
+            break;
+    }
+}
+
+static inline void sdsinclen(sds s, size_t inc) {
+    unsigned char flags = s[-1];
+    switch(flags&SDS_TYPE_MASK) {
+        case SDS_TYPE_5:
+            {
+                unsigned char *fp = ((unsigned char*)s)-1;
+                unsigned char newlen = SDS_TYPE_5_LEN(flags)+(unsigned char)inc;
+                *fp = SDS_TYPE_5 | (newlen << SDS_TYPE_BITS);
+            }
+            break;
+        case SDS_TYPE_8:
+            SDS_HDR(8,s)->len += (uint8_t)inc;
+            break;
+        case SDS_TYPE_16:
+            SDS_HDR(16,s)->len += (uint16_t)inc;
+            break;
+        case SDS_TYPE_32:
+            SDS_HDR(32,s)->len += (uint32_t)inc;
+            break;
+        case SDS_TYPE_64:
+            SDS_HDR(64,s)->len += (uint64_t)inc;
+            break;
+    }
+}
+
+/* sdsalloc() = sdsavail() + sdslen() */
+static inline size_t sdsalloc(const sds s) {
+    unsigned char flags = s[-1];
+    switch(flags&SDS_TYPE_MASK) {
+        case SDS_TYPE_5:
+            return SDS_TYPE_5_LEN(flags);
+        case SDS_TYPE_8:
+            return SDS_HDR(8,s)->alloc;
+        case SDS_TYPE_16:
+            return SDS_HDR(16,s)->alloc;
+        case SDS_TYPE_32:
+            return SDS_HDR(32,s)->alloc;
+        case SDS_TYPE_64:
+            return SDS_HDR(64,s)->alloc;
+    }
+    return 0;
+}
+
+static inline void sdssetalloc(sds s, size_t newlen) {
+    unsigned char flags = s[-1];
+    switch(flags&SDS_TYPE_MASK) {
+        case SDS_TYPE_5:
+            /* Nothing to do, this type has no total allocation info. */
+            break;
+        case SDS_TYPE_8:
+            SDS_HDR(8,s)->alloc = (uint8_t)newlen;
+            break;
+        case SDS_TYPE_16:
+            SDS_HDR(16,s)->alloc = (uint16_t)newlen;
+            break;
+        case SDS_TYPE_32:
+            SDS_HDR(32,s)->alloc = (uint32_t)newlen;
+            break;
+        case SDS_TYPE_64:
+            SDS_HDR(64,s)->alloc = (uint64_t)newlen;
+            break;
+    }
+}
+
+sds sdsnewlen(const void *init, size_t initlen);
+sds sdsnew(const char *init);
+sds sdsempty(void);
+sds sdsdup(const sds s);
+void sdsfree(sds s);
+sds sdsgrowzero(sds s, size_t len);
+sds sdscatlen(sds s, const void *t, size_t len);
+sds sdscat(sds s, const char *t);
+sds sdscatsds(sds s, const sds t);
+sds sdscpylen(sds s, const char *t, size_t len);
+sds sdscpy(sds s, const char *t);
+
+sds sdscatvprintf(sds s, const char *fmt, va_list ap);
+#ifdef __GNUC__
+sds sdscatprintf(sds s, const char *fmt, ...)
+    __attribute__((format(printf, 2, 3)));
+#else
+sds sdscatprintf(sds s, const char *fmt, ...);
+#endif
+
+sds sdscatfmt(sds s, char const *fmt, ...);
+sds sdstrim(sds s, const char *cset);
+int sdsrange(sds s, ssize_t start, ssize_t end);
+void sdsupdatelen(sds s);
+void sdsclear(sds s);
+int sdscmp(const sds s1, const sds s2);
+sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count);
+void sdsfreesplitres(sds *tokens, int count);
+void sdstolower(sds s);
+void sdstoupper(sds s);
+sds sdsfromlonglong(long long value);
+sds sdscatrepr(sds s, const char *p, size_t len);
+sds *sdssplitargs(const char *line, int *argc);
+sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen);
+sds sdsjoin(char **argv, int argc, char *sep);
+sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen);
+
+/* Low level functions exposed to the user API */
+sds sdsMakeRoomFor(sds s, size_t addlen);
+void sdsIncrLen(sds s, int incr);
+sds sdsRemoveFreeSpace(sds s);
+size_t sdsAllocSize(sds s);
+void *sdsAllocPtr(sds s);
+
+/* Export the allocator used by SDS to the program using SDS.
+ * Sometimes the program SDS is linked to, may use a different set of
+ * allocators, but may want to allocate or free things that SDS will
+ * respectively free or allocate. */
+void *sds_malloc(size_t size);
+void *sds_realloc(void *ptr, size_t size);
+void sds_free(void *ptr);
+
+#ifdef REDIS_TEST
+int sdsTest(int argc, char *argv[]);
+#endif
+
+#endif
diff --git a/tools/msys/mingw32/lib/ccache/bin/c++ b/tools/msys/mingw32/lib/ccache/bin/c++
new file mode 100644
index 0000000000000000000000000000000000000000..090bc9e9d7a28800804f1167fef6778bc58477ff
--- /dev/null
+++ b/tools/msys/mingw32/lib/ccache/bin/c++
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+ccache /mingw32/bin/c++ "$@"
diff --git a/tools/msys/mingw32/lib/ccache/bin/cc b/tools/msys/mingw32/lib/ccache/bin/cc
new file mode 100644
index 0000000000000000000000000000000000000000..972850b4a0226bf890e3b63efd31ca196b0e033a
--- /dev/null
+++ b/tools/msys/mingw32/lib/ccache/bin/cc
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+ccache /mingw32/bin/cc "$@"
diff --git a/tools/msys/mingw32/lib/ccache/bin/cpp b/tools/msys/mingw32/lib/ccache/bin/cpp
new file mode 100644
index 0000000000000000000000000000000000000000..75db13909f794199fcbce7cf1c08184049d6f08b
--- /dev/null
+++ b/tools/msys/mingw32/lib/ccache/bin/cpp
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+ccache /mingw32/bin/cpp "$@"
diff --git a/tools/msys/mingw32/lib/ccache/bin/g++ b/tools/msys/mingw32/lib/ccache/bin/g++
new file mode 100644
index 0000000000000000000000000000000000000000..c21437ffd048c261a323d155bf5797d36046ff23
--- /dev/null
+++ b/tools/msys/mingw32/lib/ccache/bin/g++
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+ccache /mingw32/bin/g++ "$@"
diff --git a/tools/msys/mingw32/lib/ccache/bin/gcc b/tools/msys/mingw32/lib/ccache/bin/gcc
new file mode 100644
index 0000000000000000000000000000000000000000..dabd5004ef6aff2a6fa5c0e3a42ed9cfbabc1bc3
--- /dev/null
+++ b/tools/msys/mingw32/lib/ccache/bin/gcc
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+ccache /mingw32/bin/gcc "$@"
diff --git a/tools/msys/mingw32/lib/ccache/bin/i686-w64-mingw32-c++ b/tools/msys/mingw32/lib/ccache/bin/i686-w64-mingw32-c++
new file mode 100644
index 0000000000000000000000000000000000000000..f18add84871b3f4348f81ee59d3e1787e33124dc
--- /dev/null
+++ b/tools/msys/mingw32/lib/ccache/bin/i686-w64-mingw32-c++
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+ccache /mingw32/bin/i686-w64-mingw32-c++ "$@"
diff --git a/tools/msys/mingw32/lib/ccache/bin/i686-w64-mingw32-g++ b/tools/msys/mingw32/lib/ccache/bin/i686-w64-mingw32-g++
new file mode 100644
index 0000000000000000000000000000000000000000..c60189ba9237612e9ea866bb1b98a23d1aeffa25
--- /dev/null
+++ b/tools/msys/mingw32/lib/ccache/bin/i686-w64-mingw32-g++
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+ccache /mingw32/bin/i686-w64-mingw32-g++ "$@"
diff --git a/tools/msys/mingw32/lib/ccache/bin/i686-w64-mingw32-gcc b/tools/msys/mingw32/lib/ccache/bin/i686-w64-mingw32-gcc
new file mode 100644
index 0000000000000000000000000000000000000000..4f816e5a0253878be59fc3f15ec282ae3180969c
--- /dev/null
+++ b/tools/msys/mingw32/lib/ccache/bin/i686-w64-mingw32-gcc
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+ccache /mingw32/bin/i686-w64-mingw32-gcc "$@"
diff --git a/tools/msys/mingw32/lib/libhiredis.dll.a b/tools/msys/mingw32/lib/libhiredis.dll.a
new file mode 100644
index 0000000000000000000000000000000000000000..7a6285c908fd6359a2d9d59657997c2355680ac0
Binary files /dev/null and b/tools/msys/mingw32/lib/libhiredis.dll.a differ
diff --git a/tools/msys/mingw32/lib/libhiredis_ssl.dll.a b/tools/msys/mingw32/lib/libhiredis_ssl.dll.a
new file mode 100644
index 0000000000000000000000000000000000000000..82feba4dea1cda3c02c3a054ffe9f7a2c2cb77bf
Binary files /dev/null and b/tools/msys/mingw32/lib/libhiredis_ssl.dll.a differ
diff --git a/tools/msys/mingw32/lib/pkgconfig/hiredis.pc b/tools/msys/mingw32/lib/pkgconfig/hiredis.pc
new file mode 100644
index 0000000000000000000000000000000000000000..f589f6db2a42a95b40aaf38e539a53873fc275b2
--- /dev/null
+++ b/tools/msys/mingw32/lib/pkgconfig/hiredis.pc
@@ -0,0 +1,12 @@
+prefix=/mingw32
+install_libdir=lib
+exec_prefix=${prefix}
+libdir=${exec_prefix}/${install_libdir}
+includedir=${prefix}/include
+pkgincludedir=${includedir}/hiredis
+
+Name: hiredis
+Description: Minimalistic C client library for Redis.
+Version: 1.0.0
+Libs: -L${libdir} -lhiredis
+Cflags: -I${pkgincludedir} -D_FILE_OFFSET_BITS=64
diff --git a/tools/msys/mingw32/lib/pkgconfig/hiredis_ssl.pc b/tools/msys/mingw32/lib/pkgconfig/hiredis_ssl.pc
new file mode 100644
index 0000000000000000000000000000000000000000..8fd4727f3cbcf9ec0e8a5f274a39b4737e572272
--- /dev/null
+++ b/tools/msys/mingw32/lib/pkgconfig/hiredis_ssl.pc
@@ -0,0 +1,12 @@
+prefix=/mingw32
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+pkgincludedir=${includedir}/hiredis
+
+Name: hiredis_ssl
+Description: SSL Support for hiredis.
+Version: 1.0.0
+Requires: hiredis
+Libs: -L${libdir} -lhiredis_ssl
+Libs.private: -lssl -lcrypto
diff --git a/tools/msys/mingw32/share/hiredis/hiredis-config.cmake b/tools/msys/mingw32/share/hiredis/hiredis-config.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..726a097ab1a8fd480ac795089cf3da0e1ed9229e
--- /dev/null
+++ b/tools/msys/mingw32/share/hiredis/hiredis-config.cmake
@@ -0,0 +1,37 @@
+
+####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() #######
+####### Any changes to this file will be overwritten by the next CMake run ####
+####### The input file was hiredis-config.cmake.in                            ########
+
+get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../" ABSOLUTE)
+
+macro(set_and_check _var _file)
+  set(${_var} "${_file}")
+  if(NOT EXISTS "${_file}")
+    message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !")
+  endif()
+endmacro()
+
+macro(check_required_components _NAME)
+  foreach(comp ${${_NAME}_FIND_COMPONENTS})
+    if(NOT ${_NAME}_${comp}_FOUND)
+      if(${_NAME}_FIND_REQUIRED_${comp})
+        set(${_NAME}_FOUND FALSE)
+      endif()
+    endif()
+  endforeach()
+endmacro()
+
+####################################################################################
+
+set_and_check(hiredis_INCLUDEDIR "${PACKAGE_PREFIX_DIR}/include")
+
+IF (NOT TARGET hiredis::hiredis)
+	INCLUDE(${CMAKE_CURRENT_LIST_DIR}/hiredis-targets.cmake)
+ENDIF()
+
+SET(hiredis_LIBRARIES hiredis::hiredis)
+SET(hiredis_INCLUDE_DIRS ${hiredis_INCLUDEDIR})
+
+check_required_components(hiredis)
+
diff --git a/tools/msys/mingw32/share/hiredis/hiredis-targets-noconfig.cmake b/tools/msys/mingw32/share/hiredis/hiredis-targets-noconfig.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..689663ef3d197695549195b887dfb63df09f9a08
--- /dev/null
+++ b/tools/msys/mingw32/share/hiredis/hiredis-targets-noconfig.cmake
@@ -0,0 +1,19 @@
+#----------------------------------------------------------------
+# Generated CMake target import file.
+#----------------------------------------------------------------
+
+# Commands may need to know the format version.
+set(CMAKE_IMPORT_FILE_VERSION 1)
+
+# Import target "hiredis::hiredis" for configuration ""
+set_property(TARGET hiredis::hiredis APPEND PROPERTY IMPORTED_CONFIGURATIONS NOCONFIG)
+set_target_properties(hiredis::hiredis PROPERTIES
+  IMPORTED_IMPLIB_NOCONFIG "${_IMPORT_PREFIX}/lib/libhiredis.dll.a"
+  IMPORTED_LOCATION_NOCONFIG "${_IMPORT_PREFIX}/bin/libhiredis.dll"
+  )
+
+list(APPEND _IMPORT_CHECK_TARGETS hiredis::hiredis )
+list(APPEND _IMPORT_CHECK_FILES_FOR_hiredis::hiredis "${_IMPORT_PREFIX}/lib/libhiredis.dll.a" "${_IMPORT_PREFIX}/bin/libhiredis.dll" )
+
+# Commands beyond this point should not need to know the version.
+set(CMAKE_IMPORT_FILE_VERSION)
diff --git a/tools/msys/mingw32/share/hiredis/hiredis-targets.cmake b/tools/msys/mingw32/share/hiredis/hiredis-targets.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..39ec3dd6e3e4b150be47c709a6a71467fd8fb943
--- /dev/null
+++ b/tools/msys/mingw32/share/hiredis/hiredis-targets.cmake
@@ -0,0 +1,93 @@
+# Generated by CMake
+
+if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.5)
+   message(FATAL_ERROR "CMake >= 2.6.0 required")
+endif()
+cmake_policy(PUSH)
+cmake_policy(VERSION 2.6...3.17)
+#----------------------------------------------------------------
+# Generated CMake target import file.
+#----------------------------------------------------------------
+
+# Commands may need to know the format version.
+set(CMAKE_IMPORT_FILE_VERSION 1)
+
+# Protect against multiple inclusion, which would fail when already imported targets are added once more.
+set(_targetsDefined)
+set(_targetsNotDefined)
+set(_expectedTargets)
+foreach(_expectedTarget hiredis::hiredis)
+  list(APPEND _expectedTargets ${_expectedTarget})
+  if(NOT TARGET ${_expectedTarget})
+    list(APPEND _targetsNotDefined ${_expectedTarget})
+  endif()
+  if(TARGET ${_expectedTarget})
+    list(APPEND _targetsDefined ${_expectedTarget})
+  endif()
+endforeach()
+if("${_targetsDefined}" STREQUAL "${_expectedTargets}")
+  unset(_targetsDefined)
+  unset(_targetsNotDefined)
+  unset(_expectedTargets)
+  set(CMAKE_IMPORT_FILE_VERSION)
+  cmake_policy(POP)
+  return()
+endif()
+if(NOT "${_targetsDefined}" STREQUAL "")
+  message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_targetsDefined}\nTargets not yet defined: ${_targetsNotDefined}\n")
+endif()
+unset(_targetsDefined)
+unset(_targetsNotDefined)
+unset(_expectedTargets)
+
+
+# Compute the installation prefix relative to this file.
+get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
+get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
+get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
+if(_IMPORT_PREFIX STREQUAL "/")
+  set(_IMPORT_PREFIX "")
+endif()
+
+# Create imported target hiredis::hiredis
+add_library(hiredis::hiredis SHARED IMPORTED)
+
+set_target_properties(hiredis::hiredis PROPERTIES
+  INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/."
+)
+
+# Load information for each installed configuration.
+get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
+file(GLOB CONFIG_FILES "${_DIR}/hiredis-targets-*.cmake")
+foreach(f ${CONFIG_FILES})
+  include(${f})
+endforeach()
+
+# Cleanup temporary variables.
+set(_IMPORT_PREFIX)
+
+# Loop over all imported files and verify that they actually exist
+foreach(target ${_IMPORT_CHECK_TARGETS} )
+  foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} )
+    if(NOT EXISTS "${file}" )
+      message(FATAL_ERROR "The imported target \"${target}\" references the file
+   \"${file}\"
+but this file does not exist.  Possible reasons include:
+* The file was deleted, renamed, or moved to another location.
+* An install or uninstall procedure did not complete successfully.
+* The installation package was faulty and contained
+   \"${CMAKE_CURRENT_LIST_FILE}\"
+but not all the files it references.
+")
+    endif()
+  endforeach()
+  unset(_IMPORT_CHECK_FILES_FOR_${target})
+endforeach()
+unset(_IMPORT_CHECK_TARGETS)
+
+# This file does not depend on other imported targets which have
+# been exported from the same project but in a separate export set.
+
+# Commands beyond this point should not need to know the version.
+set(CMAKE_IMPORT_FILE_VERSION)
+cmake_policy(POP)
diff --git a/tools/msys/mingw32/share/hiredis_ssl/hiredis_ssl-config.cmake b/tools/msys/mingw32/share/hiredis_ssl/hiredis_ssl-config.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..3f69b2968e16522cea0e0108cca66eb9994cc2b4
--- /dev/null
+++ b/tools/msys/mingw32/share/hiredis_ssl/hiredis_ssl-config.cmake
@@ -0,0 +1,37 @@
+
+####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() #######
+####### Any changes to this file will be overwritten by the next CMake run ####
+####### The input file was hiredis_ssl-config.cmake.in                            ########
+
+get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../" ABSOLUTE)
+
+macro(set_and_check _var _file)
+  set(${_var} "${_file}")
+  if(NOT EXISTS "${_file}")
+    message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !")
+  endif()
+endmacro()
+
+macro(check_required_components _NAME)
+  foreach(comp ${${_NAME}_FIND_COMPONENTS})
+    if(NOT ${_NAME}_${comp}_FOUND)
+      if(${_NAME}_FIND_REQUIRED_${comp})
+        set(${_NAME}_FOUND FALSE)
+      endif()
+    endif()
+  endforeach()
+endmacro()
+
+####################################################################################
+
+set_and_check(hiredis_ssl_INCLUDEDIR "${PACKAGE_PREFIX_DIR}/include")
+
+IF (NOT TARGET hiredis::hiredis_ssl)
+	INCLUDE(${CMAKE_CURRENT_LIST_DIR}/hiredis_ssl-targets.cmake)
+ENDIF()
+
+SET(hiredis_ssl_LIBRARIES hiredis::hiredis_ssl)
+SET(hiredis_ssl_INCLUDE_DIRS ${hiredis_ssl_INCLUDEDIR})
+
+check_required_components(hiredis_ssl)
+
diff --git a/tools/msys/mingw32/share/hiredis_ssl/hiredis_ssl-targets-noconfig.cmake b/tools/msys/mingw32/share/hiredis_ssl/hiredis_ssl-targets-noconfig.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..9eb922db60d43e724429cb0427f75dd9a31d4af4
--- /dev/null
+++ b/tools/msys/mingw32/share/hiredis_ssl/hiredis_ssl-targets-noconfig.cmake
@@ -0,0 +1,20 @@
+#----------------------------------------------------------------
+# Generated CMake target import file.
+#----------------------------------------------------------------
+
+# Commands may need to know the format version.
+set(CMAKE_IMPORT_FILE_VERSION 1)
+
+# Import target "hiredis::hiredis_ssl" for configuration ""
+set_property(TARGET hiredis::hiredis_ssl APPEND PROPERTY IMPORTED_CONFIGURATIONS NOCONFIG)
+set_target_properties(hiredis::hiredis_ssl PROPERTIES
+  IMPORTED_IMPLIB_NOCONFIG "${_IMPORT_PREFIX}/lib/libhiredis_ssl.dll.a"
+  IMPORTED_LINK_DEPENDENT_LIBRARIES_NOCONFIG "hiredis::hiredis"
+  IMPORTED_LOCATION_NOCONFIG "${_IMPORT_PREFIX}/bin/libhiredis_ssl.dll"
+  )
+
+list(APPEND _IMPORT_CHECK_TARGETS hiredis::hiredis_ssl )
+list(APPEND _IMPORT_CHECK_FILES_FOR_hiredis::hiredis_ssl "${_IMPORT_PREFIX}/lib/libhiredis_ssl.dll.a" "${_IMPORT_PREFIX}/bin/libhiredis_ssl.dll" )
+
+# Commands beyond this point should not need to know the version.
+set(CMAKE_IMPORT_FILE_VERSION)
diff --git a/tools/msys/mingw32/share/hiredis_ssl/hiredis_ssl-targets.cmake b/tools/msys/mingw32/share/hiredis_ssl/hiredis_ssl-targets.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..e033d901e2189e9fef9a657d900d1870b54183f6
--- /dev/null
+++ b/tools/msys/mingw32/share/hiredis_ssl/hiredis_ssl-targets.cmake
@@ -0,0 +1,89 @@
+# Generated by CMake
+
+if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.5)
+   message(FATAL_ERROR "CMake >= 2.6.0 required")
+endif()
+cmake_policy(PUSH)
+cmake_policy(VERSION 2.6...3.17)
+#----------------------------------------------------------------
+# Generated CMake target import file.
+#----------------------------------------------------------------
+
+# Commands may need to know the format version.
+set(CMAKE_IMPORT_FILE_VERSION 1)
+
+# Protect against multiple inclusion, which would fail when already imported targets are added once more.
+set(_targetsDefined)
+set(_targetsNotDefined)
+set(_expectedTargets)
+foreach(_expectedTarget hiredis::hiredis_ssl)
+  list(APPEND _expectedTargets ${_expectedTarget})
+  if(NOT TARGET ${_expectedTarget})
+    list(APPEND _targetsNotDefined ${_expectedTarget})
+  endif()
+  if(TARGET ${_expectedTarget})
+    list(APPEND _targetsDefined ${_expectedTarget})
+  endif()
+endforeach()
+if("${_targetsDefined}" STREQUAL "${_expectedTargets}")
+  unset(_targetsDefined)
+  unset(_targetsNotDefined)
+  unset(_expectedTargets)
+  set(CMAKE_IMPORT_FILE_VERSION)
+  cmake_policy(POP)
+  return()
+endif()
+if(NOT "${_targetsDefined}" STREQUAL "")
+  message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_targetsDefined}\nTargets not yet defined: ${_targetsNotDefined}\n")
+endif()
+unset(_targetsDefined)
+unset(_targetsNotDefined)
+unset(_expectedTargets)
+
+
+# Compute the installation prefix relative to this file.
+get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
+get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
+get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
+if(_IMPORT_PREFIX STREQUAL "/")
+  set(_IMPORT_PREFIX "")
+endif()
+
+# Create imported target hiredis::hiredis_ssl
+add_library(hiredis::hiredis_ssl SHARED IMPORTED)
+
+# Load information for each installed configuration.
+get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
+file(GLOB CONFIG_FILES "${_DIR}/hiredis_ssl-targets-*.cmake")
+foreach(f ${CONFIG_FILES})
+  include(${f})
+endforeach()
+
+# Cleanup temporary variables.
+set(_IMPORT_PREFIX)
+
+# Loop over all imported files and verify that they actually exist
+foreach(target ${_IMPORT_CHECK_TARGETS} )
+  foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} )
+    if(NOT EXISTS "${file}" )
+      message(FATAL_ERROR "The imported target \"${target}\" references the file
+   \"${file}\"
+but this file does not exist.  Possible reasons include:
+* The file was deleted, renamed, or moved to another location.
+* An install or uninstall procedure did not complete successfully.
+* The installation package was faulty and contained
+   \"${CMAKE_CURRENT_LIST_FILE}\"
+but not all the files it references.
+")
+    endif()
+  endforeach()
+  unset(_IMPORT_CHECK_FILES_FOR_${target})
+endforeach()
+unset(_IMPORT_CHECK_TARGETS)
+
+# This file does not depend on other imported targets which have
+# been exported from the same project but in a separate export set.
+
+# Commands beyond this point should not need to know the version.
+set(CMAKE_IMPORT_FILE_VERSION)
+cmake_policy(POP)
diff --git a/tools/msys/mingw32/share/man/man1/ccache.1.gz b/tools/msys/mingw32/share/man/man1/ccache.1.gz
new file mode 100644
index 0000000000000000000000000000000000000000..988645578c71dd63dcb58f25960a37f2ed99704b
Binary files /dev/null and b/tools/msys/mingw32/share/man/man1/ccache.1.gz differ
diff --git a/tools/msys/mingw64/bin/ccache.exe b/tools/msys/mingw64/bin/ccache.exe
new file mode 100644
index 0000000000000000000000000000000000000000..9b4c6f37be52667f18425dbeecd157c1430927a7
Binary files /dev/null and b/tools/msys/mingw64/bin/ccache.exe differ
diff --git a/tools/msys/mingw64/bin/libhiredis.dll b/tools/msys/mingw64/bin/libhiredis.dll
new file mode 100644
index 0000000000000000000000000000000000000000..44e5c520c182beb3e896e1eae8ba91331e09b5b9
Binary files /dev/null and b/tools/msys/mingw64/bin/libhiredis.dll differ
diff --git a/tools/msys/mingw64/bin/libhiredis_ssl.dll b/tools/msys/mingw64/bin/libhiredis_ssl.dll
new file mode 100644
index 0000000000000000000000000000000000000000..2f0f2710837da60065742aef042d075db4c80262
Binary files /dev/null and b/tools/msys/mingw64/bin/libhiredis_ssl.dll differ
diff --git a/tools/msys/mingw64/include/hiredis/adapters/ae.h b/tools/msys/mingw64/include/hiredis/adapters/ae.h
new file mode 100644
index 0000000000000000000000000000000000000000..660d82eb0cecebbd574d1743bfa94090a408479d
--- /dev/null
+++ b/tools/msys/mingw64/include/hiredis/adapters/ae.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of Redis nor the names of its contributors may be used
+ *     to endorse or promote products derived from this software without
+ *     specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __HIREDIS_AE_H__
+#define __HIREDIS_AE_H__
+#include <sys/types.h>
+#include <ae.h>
+#include "../hiredis.h"
+#include "../async.h"
+
+typedef struct redisAeEvents {
+    redisAsyncContext *context;
+    aeEventLoop *loop;
+    int fd;
+    int reading, writing;
+} redisAeEvents;
+
+static void redisAeReadEvent(aeEventLoop *el, int fd, void *privdata, int mask) {
+    ((void)el); ((void)fd); ((void)mask);
+
+    redisAeEvents *e = (redisAeEvents*)privdata;
+    redisAsyncHandleRead(e->context);
+}
+
+static void redisAeWriteEvent(aeEventLoop *el, int fd, void *privdata, int mask) {
+    ((void)el); ((void)fd); ((void)mask);
+
+    redisAeEvents *e = (redisAeEvents*)privdata;
+    redisAsyncHandleWrite(e->context);
+}
+
+static void redisAeAddRead(void *privdata) {
+    redisAeEvents *e = (redisAeEvents*)privdata;
+    aeEventLoop *loop = e->loop;
+    if (!e->reading) {
+        e->reading = 1;
+        aeCreateFileEvent(loop,e->fd,AE_READABLE,redisAeReadEvent,e);
+    }
+}
+
+static void redisAeDelRead(void *privdata) {
+    redisAeEvents *e = (redisAeEvents*)privdata;
+    aeEventLoop *loop = e->loop;
+    if (e->reading) {
+        e->reading = 0;
+        aeDeleteFileEvent(loop,e->fd,AE_READABLE);
+    }
+}
+
+static void redisAeAddWrite(void *privdata) {
+    redisAeEvents *e = (redisAeEvents*)privdata;
+    aeEventLoop *loop = e->loop;
+    if (!e->writing) {
+        e->writing = 1;
+        aeCreateFileEvent(loop,e->fd,AE_WRITABLE,redisAeWriteEvent,e);
+    }
+}
+
+static void redisAeDelWrite(void *privdata) {
+    redisAeEvents *e = (redisAeEvents*)privdata;
+    aeEventLoop *loop = e->loop;
+    if (e->writing) {
+        e->writing = 0;
+        aeDeleteFileEvent(loop,e->fd,AE_WRITABLE);
+    }
+}
+
+static void redisAeCleanup(void *privdata) {
+    redisAeEvents *e = (redisAeEvents*)privdata;
+    redisAeDelRead(privdata);
+    redisAeDelWrite(privdata);
+    hi_free(e);
+}
+
+static int redisAeAttach(aeEventLoop *loop, redisAsyncContext *ac) {
+    redisContext *c = &(ac->c);
+    redisAeEvents *e;
+
+    /* Nothing should be attached when something is already attached */
+    if (ac->ev.data != NULL)
+        return REDIS_ERR;
+
+    /* Create container for context and r/w events */
+    e = (redisAeEvents*)hi_malloc(sizeof(*e));
+    if (e == NULL)
+        return REDIS_ERR;
+
+    e->context = ac;
+    e->loop = loop;
+    e->fd = c->fd;
+    e->reading = e->writing = 0;
+
+    /* Register functions to start/stop listening for events */
+    ac->ev.addRead = redisAeAddRead;
+    ac->ev.delRead = redisAeDelRead;
+    ac->ev.addWrite = redisAeAddWrite;
+    ac->ev.delWrite = redisAeDelWrite;
+    ac->ev.cleanup = redisAeCleanup;
+    ac->ev.data = e;
+
+    return REDIS_OK;
+}
+#endif
diff --git a/tools/msys/mingw64/include/hiredis/adapters/glib.h b/tools/msys/mingw64/include/hiredis/adapters/glib.h
new file mode 100644
index 0000000000000000000000000000000000000000..ad59dd14275183254313ffe505ea8b5b1d9c33ba
--- /dev/null
+++ b/tools/msys/mingw64/include/hiredis/adapters/glib.h
@@ -0,0 +1,156 @@
+#ifndef __HIREDIS_GLIB_H__
+#define __HIREDIS_GLIB_H__
+
+#include <glib.h>
+
+#include "../hiredis.h"
+#include "../async.h"
+
+typedef struct
+{
+    GSource source;
+    redisAsyncContext *ac;
+    GPollFD poll_fd;
+} RedisSource;
+
+static void
+redis_source_add_read (gpointer data)
+{
+    RedisSource *source = (RedisSource *)data;
+    g_return_if_fail(source);
+    source->poll_fd.events |= G_IO_IN;
+    g_main_context_wakeup(g_source_get_context((GSource *)data));
+}
+
+static void
+redis_source_del_read (gpointer data)
+{
+    RedisSource *source = (RedisSource *)data;
+    g_return_if_fail(source);
+    source->poll_fd.events &= ~G_IO_IN;
+    g_main_context_wakeup(g_source_get_context((GSource *)data));
+}
+
+static void
+redis_source_add_write (gpointer data)
+{
+    RedisSource *source = (RedisSource *)data;
+    g_return_if_fail(source);
+    source->poll_fd.events |= G_IO_OUT;
+    g_main_context_wakeup(g_source_get_context((GSource *)data));
+}
+
+static void
+redis_source_del_write (gpointer data)
+{
+    RedisSource *source = (RedisSource *)data;
+    g_return_if_fail(source);
+    source->poll_fd.events &= ~G_IO_OUT;
+    g_main_context_wakeup(g_source_get_context((GSource *)data));
+}
+
+static void
+redis_source_cleanup (gpointer data)
+{
+    RedisSource *source = (RedisSource *)data;
+
+    g_return_if_fail(source);
+
+    redis_source_del_read(source);
+    redis_source_del_write(source);
+    /*
+     * It is not our responsibility to remove ourself from the
+     * current main loop. However, we will remove the GPollFD.
+     */
+    if (source->poll_fd.fd >= 0) {
+        g_source_remove_poll((GSource *)data, &source->poll_fd);
+        source->poll_fd.fd = -1;
+    }
+}
+
+static gboolean
+redis_source_prepare (GSource *source,
+                      gint    *timeout_)
+{
+    RedisSource *redis = (RedisSource *)source;
+    *timeout_ = -1;
+    return !!(redis->poll_fd.events & redis->poll_fd.revents);
+}
+
+static gboolean
+redis_source_check (GSource *source)
+{
+    RedisSource *redis = (RedisSource *)source;
+    return !!(redis->poll_fd.events & redis->poll_fd.revents);
+}
+
+static gboolean
+redis_source_dispatch (GSource      *source,
+                       GSourceFunc   callback,
+                       gpointer      user_data)
+{
+    RedisSource *redis = (RedisSource *)source;
+
+    if ((redis->poll_fd.revents & G_IO_OUT)) {
+        redisAsyncHandleWrite(redis->ac);
+        redis->poll_fd.revents &= ~G_IO_OUT;
+    }
+
+    if ((redis->poll_fd.revents & G_IO_IN)) {
+        redisAsyncHandleRead(redis->ac);
+        redis->poll_fd.revents &= ~G_IO_IN;
+    }
+
+    if (callback) {
+        return callback(user_data);
+    }
+
+    return TRUE;
+}
+
+static void
+redis_source_finalize (GSource *source)
+{
+    RedisSource *redis = (RedisSource *)source;
+
+    if (redis->poll_fd.fd >= 0) {
+        g_source_remove_poll(source, &redis->poll_fd);
+        redis->poll_fd.fd = -1;
+    }
+}
+
+static GSource *
+redis_source_new (redisAsyncContext *ac)
+{
+    static GSourceFuncs source_funcs = {
+        .prepare  = redis_source_prepare,
+        .check     = redis_source_check,
+        .dispatch = redis_source_dispatch,
+        .finalize = redis_source_finalize,
+    };
+    redisContext *c = &ac->c;
+    RedisSource *source;
+
+    g_return_val_if_fail(ac != NULL, NULL);
+
+    source = (RedisSource *)g_source_new(&source_funcs, sizeof *source);
+    if (source == NULL)
+        return NULL;
+
+    source->ac = ac;
+    source->poll_fd.fd = c->fd;
+    source->poll_fd.events = 0;
+    source->poll_fd.revents = 0;
+    g_source_add_poll((GSource *)source, &source->poll_fd);
+
+    ac->ev.addRead = redis_source_add_read;
+    ac->ev.delRead = redis_source_del_read;
+    ac->ev.addWrite = redis_source_add_write;
+    ac->ev.delWrite = redis_source_del_write;
+    ac->ev.cleanup = redis_source_cleanup;
+    ac->ev.data = source;
+
+    return (GSource *)source;
+}
+
+#endif /* __HIREDIS_GLIB_H__ */
diff --git a/tools/msys/mingw64/include/hiredis/adapters/ivykis.h b/tools/msys/mingw64/include/hiredis/adapters/ivykis.h
new file mode 100644
index 0000000000000000000000000000000000000000..179f6ab523701fa8a54bcb13db2608d7beb4f079
--- /dev/null
+++ b/tools/msys/mingw64/include/hiredis/adapters/ivykis.h
@@ -0,0 +1,84 @@
+#ifndef __HIREDIS_IVYKIS_H__
+#define __HIREDIS_IVYKIS_H__
+#include <iv.h>
+#include "../hiredis.h"
+#include "../async.h"
+
+typedef struct redisIvykisEvents {
+    redisAsyncContext *context;
+    struct iv_fd fd;
+} redisIvykisEvents;
+
+static void redisIvykisReadEvent(void *arg) {
+    redisAsyncContext *context = (redisAsyncContext *)arg;
+    redisAsyncHandleRead(context);
+}
+
+static void redisIvykisWriteEvent(void *arg) {
+    redisAsyncContext *context = (redisAsyncContext *)arg;
+    redisAsyncHandleWrite(context);
+}
+
+static void redisIvykisAddRead(void *privdata) {
+    redisIvykisEvents *e = (redisIvykisEvents*)privdata;
+    iv_fd_set_handler_in(&e->fd, redisIvykisReadEvent);
+}
+
+static void redisIvykisDelRead(void *privdata) {
+    redisIvykisEvents *e = (redisIvykisEvents*)privdata;
+    iv_fd_set_handler_in(&e->fd, NULL);
+}
+
+static void redisIvykisAddWrite(void *privdata) {
+    redisIvykisEvents *e = (redisIvykisEvents*)privdata;
+    iv_fd_set_handler_out(&e->fd, redisIvykisWriteEvent);
+}
+
+static void redisIvykisDelWrite(void *privdata) {
+    redisIvykisEvents *e = (redisIvykisEvents*)privdata;
+    iv_fd_set_handler_out(&e->fd, NULL);
+}
+
+static void redisIvykisCleanup(void *privdata) {
+    redisIvykisEvents *e = (redisIvykisEvents*)privdata;
+
+    iv_fd_unregister(&e->fd);
+    hi_free(e);
+}
+
+static int redisIvykisAttach(redisAsyncContext *ac) {
+    redisContext *c = &(ac->c);
+    redisIvykisEvents *e;
+
+    /* Nothing should be attached when something is already attached */
+    if (ac->ev.data != NULL)
+        return REDIS_ERR;
+
+    /* Create container for context and r/w events */
+    e = (redisIvykisEvents*)hi_malloc(sizeof(*e));
+    if (e == NULL)
+        return REDIS_ERR;
+
+    e->context = ac;
+
+    /* Register functions to start/stop listening for events */
+    ac->ev.addRead = redisIvykisAddRead;
+    ac->ev.delRead = redisIvykisDelRead;
+    ac->ev.addWrite = redisIvykisAddWrite;
+    ac->ev.delWrite = redisIvykisDelWrite;
+    ac->ev.cleanup = redisIvykisCleanup;
+    ac->ev.data = e;
+
+    /* Initialize and install read/write events */
+    IV_FD_INIT(&e->fd);
+    e->fd.fd = c->fd;
+    e->fd.handler_in = redisIvykisReadEvent;
+    e->fd.handler_out = redisIvykisWriteEvent;
+    e->fd.handler_err = NULL;
+    e->fd.cookie = e->context;
+
+    iv_fd_register(&e->fd);
+
+    return REDIS_OK;
+}
+#endif
diff --git a/tools/msys/mingw64/include/hiredis/adapters/libev.h b/tools/msys/mingw64/include/hiredis/adapters/libev.h
new file mode 100644
index 0000000000000000000000000000000000000000..e1e7bbd99c9473cffe6f7ce0c7b546550e834d00
--- /dev/null
+++ b/tools/msys/mingw64/include/hiredis/adapters/libev.h
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of Redis nor the names of its contributors may be used
+ *     to endorse or promote products derived from this software without
+ *     specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __HIREDIS_LIBEV_H__
+#define __HIREDIS_LIBEV_H__
+#include <stdlib.h>
+#include <sys/types.h>
+#include <ev.h>
+#include "../hiredis.h"
+#include "../async.h"
+
+typedef struct redisLibevEvents {
+    redisAsyncContext *context;
+    struct ev_loop *loop;
+    int reading, writing;
+    ev_io rev, wev;
+    ev_timer timer;
+} redisLibevEvents;
+
+static void redisLibevReadEvent(EV_P_ ev_io *watcher, int revents) {
+#if EV_MULTIPLICITY
+    ((void)loop);
+#endif
+    ((void)revents);
+
+    redisLibevEvents *e = (redisLibevEvents*)watcher->data;
+    redisAsyncHandleRead(e->context);
+}
+
+static void redisLibevWriteEvent(EV_P_ ev_io *watcher, int revents) {
+#if EV_MULTIPLICITY
+    ((void)loop);
+#endif
+    ((void)revents);
+
+    redisLibevEvents *e = (redisLibevEvents*)watcher->data;
+    redisAsyncHandleWrite(e->context);
+}
+
+static void redisLibevAddRead(void *privdata) {
+    redisLibevEvents *e = (redisLibevEvents*)privdata;
+    struct ev_loop *loop = e->loop;
+    ((void)loop);
+    if (!e->reading) {
+        e->reading = 1;
+        ev_io_start(EV_A_ &e->rev);
+    }
+}
+
+static void redisLibevDelRead(void *privdata) {
+    redisLibevEvents *e = (redisLibevEvents*)privdata;
+    struct ev_loop *loop = e->loop;
+    ((void)loop);
+    if (e->reading) {
+        e->reading = 0;
+        ev_io_stop(EV_A_ &e->rev);
+    }
+}
+
+static void redisLibevAddWrite(void *privdata) {
+    redisLibevEvents *e = (redisLibevEvents*)privdata;
+    struct ev_loop *loop = e->loop;
+    ((void)loop);
+    if (!e->writing) {
+        e->writing = 1;
+        ev_io_start(EV_A_ &e->wev);
+    }
+}
+
+static void redisLibevDelWrite(void *privdata) {
+    redisLibevEvents *e = (redisLibevEvents*)privdata;
+    struct ev_loop *loop = e->loop;
+    ((void)loop);
+    if (e->writing) {
+        e->writing = 0;
+        ev_io_stop(EV_A_ &e->wev);
+    }
+}
+
+static void redisLibevStopTimer(void *privdata) {
+    redisLibevEvents *e = (redisLibevEvents*)privdata;
+    struct ev_loop *loop = e->loop;
+    ((void)loop);
+    ev_timer_stop(EV_A_ &e->timer);
+}
+
+static void redisLibevCleanup(void *privdata) {
+    redisLibevEvents *e = (redisLibevEvents*)privdata;
+    redisLibevDelRead(privdata);
+    redisLibevDelWrite(privdata);
+    redisLibevStopTimer(privdata);
+    hi_free(e);
+}
+
+static void redisLibevTimeout(EV_P_ ev_timer *timer, int revents) {
+    ((void)revents);
+    redisLibevEvents *e = (redisLibevEvents*)timer->data;
+    redisAsyncHandleTimeout(e->context);
+}
+
+static void redisLibevSetTimeout(void *privdata, struct timeval tv) {
+    redisLibevEvents *e = (redisLibevEvents*)privdata;
+    struct ev_loop *loop = e->loop;
+    ((void)loop);
+
+    if (!ev_is_active(&e->timer)) {
+        ev_init(&e->timer, redisLibevTimeout);
+        e->timer.data = e;
+    }
+
+    e->timer.repeat = tv.tv_sec + tv.tv_usec / 1000000.00;
+    ev_timer_again(EV_A_ &e->timer);
+}
+
+static int redisLibevAttach(EV_P_ redisAsyncContext *ac) {
+    redisContext *c = &(ac->c);
+    redisLibevEvents *e;
+
+    /* Nothing should be attached when something is already attached */
+    if (ac->ev.data != NULL)
+        return REDIS_ERR;
+
+    /* Create container for context and r/w events */
+    e = (redisLibevEvents*)hi_calloc(1, sizeof(*e));
+    if (e == NULL)
+        return REDIS_ERR;
+
+    e->context = ac;
+#if EV_MULTIPLICITY
+    e->loop = loop;
+#else
+    e->loop = NULL;
+#endif
+    e->rev.data = e;
+    e->wev.data = e;
+
+    /* Register functions to start/stop listening for events */
+    ac->ev.addRead = redisLibevAddRead;
+    ac->ev.delRead = redisLibevDelRead;
+    ac->ev.addWrite = redisLibevAddWrite;
+    ac->ev.delWrite = redisLibevDelWrite;
+    ac->ev.cleanup = redisLibevCleanup;
+    ac->ev.scheduleTimer = redisLibevSetTimeout;
+    ac->ev.data = e;
+
+    /* Initialize read/write events */
+    ev_io_init(&e->rev,redisLibevReadEvent,c->fd,EV_READ);
+    ev_io_init(&e->wev,redisLibevWriteEvent,c->fd,EV_WRITE);
+    return REDIS_OK;
+}
+
+#endif
diff --git a/tools/msys/mingw64/include/hiredis/adapters/libevent.h b/tools/msys/mingw64/include/hiredis/adapters/libevent.h
new file mode 100644
index 0000000000000000000000000000000000000000..9150979bc6c55b417458f57fcae156c860823a45
--- /dev/null
+++ b/tools/msys/mingw64/include/hiredis/adapters/libevent.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of Redis nor the names of its contributors may be used
+ *     to endorse or promote products derived from this software without
+ *     specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __HIREDIS_LIBEVENT_H__
+#define __HIREDIS_LIBEVENT_H__
+#include <event2/event.h>
+#include "../hiredis.h"
+#include "../async.h"
+
+#define REDIS_LIBEVENT_DELETED 0x01
+#define REDIS_LIBEVENT_ENTERED 0x02
+
+typedef struct redisLibeventEvents {
+    redisAsyncContext *context;
+    struct event *ev;
+    struct event_base *base;
+    struct timeval tv;
+    short flags;
+    short state;
+} redisLibeventEvents;
+
+static void redisLibeventDestroy(redisLibeventEvents *e) {
+    hi_free(e);
+}
+
+static void redisLibeventHandler(int fd, short event, void *arg) {
+    ((void)fd);
+    redisLibeventEvents *e = (redisLibeventEvents*)arg;
+    e->state |= REDIS_LIBEVENT_ENTERED;
+
+    #define CHECK_DELETED() if (e->state & REDIS_LIBEVENT_DELETED) {\
+        redisLibeventDestroy(e);\
+        return; \
+    }
+
+    if ((event & EV_TIMEOUT) && (e->state & REDIS_LIBEVENT_DELETED) == 0) {
+        redisAsyncHandleTimeout(e->context);
+        CHECK_DELETED();
+    }
+
+    if ((event & EV_READ) && e->context && (e->state & REDIS_LIBEVENT_DELETED) == 0) {
+        redisAsyncHandleRead(e->context);
+        CHECK_DELETED();
+    }
+
+    if ((event & EV_WRITE) && e->context && (e->state & REDIS_LIBEVENT_DELETED) == 0) {
+        redisAsyncHandleWrite(e->context);
+        CHECK_DELETED();
+    }
+
+    e->state &= ~REDIS_LIBEVENT_ENTERED;
+    #undef CHECK_DELETED
+}
+
+static void redisLibeventUpdate(void *privdata, short flag, int isRemove) {
+    redisLibeventEvents *e = (redisLibeventEvents *)privdata;
+    const struct timeval *tv = e->tv.tv_sec || e->tv.tv_usec ? &e->tv : NULL;
+
+    if (isRemove) {
+        if ((e->flags & flag) == 0) {
+            return;
+        } else {
+            e->flags &= ~flag;
+        }
+    } else {
+        if (e->flags & flag) {
+            return;
+        } else {
+            e->flags |= flag;
+        }
+    }
+
+    event_del(e->ev);
+    event_assign(e->ev, e->base, e->context->c.fd, e->flags | EV_PERSIST,
+                 redisLibeventHandler, privdata);
+    event_add(e->ev, tv);
+}
+
+static void redisLibeventAddRead(void *privdata) {
+    redisLibeventUpdate(privdata, EV_READ, 0);
+}
+
+static void redisLibeventDelRead(void *privdata) {
+    redisLibeventUpdate(privdata, EV_READ, 1);
+}
+
+static void redisLibeventAddWrite(void *privdata) {
+    redisLibeventUpdate(privdata, EV_WRITE, 0);
+}
+
+static void redisLibeventDelWrite(void *privdata) {
+    redisLibeventUpdate(privdata, EV_WRITE, 1);
+}
+
+static void redisLibeventCleanup(void *privdata) {
+    redisLibeventEvents *e = (redisLibeventEvents*)privdata;
+    if (!e) {
+        return;
+    }
+    event_del(e->ev);
+    event_free(e->ev);
+    e->ev = NULL;
+
+    if (e->state & REDIS_LIBEVENT_ENTERED) {
+        e->state |= REDIS_LIBEVENT_DELETED;
+    } else {
+        redisLibeventDestroy(e);
+    }
+}
+
+static void redisLibeventSetTimeout(void *privdata, struct timeval tv) {
+    redisLibeventEvents *e = (redisLibeventEvents *)privdata;
+    short flags = e->flags;
+    e->flags = 0;
+    e->tv = tv;
+    redisLibeventUpdate(e, flags, 0);
+}
+
+static int redisLibeventAttach(redisAsyncContext *ac, struct event_base *base) {
+    redisContext *c = &(ac->c);
+    redisLibeventEvents *e;
+
+    /* Nothing should be attached when something is already attached */
+    if (ac->ev.data != NULL)
+        return REDIS_ERR;
+
+    /* Create container for context and r/w events */
+    e = (redisLibeventEvents*)hi_calloc(1, sizeof(*e));
+    if (e == NULL)
+        return REDIS_ERR;
+
+    e->context = ac;
+
+    /* Register functions to start/stop listening for events */
+    ac->ev.addRead = redisLibeventAddRead;
+    ac->ev.delRead = redisLibeventDelRead;
+    ac->ev.addWrite = redisLibeventAddWrite;
+    ac->ev.delWrite = redisLibeventDelWrite;
+    ac->ev.cleanup = redisLibeventCleanup;
+    ac->ev.scheduleTimer = redisLibeventSetTimeout;
+    ac->ev.data = e;
+
+    /* Initialize and install read/write events */
+    e->ev = event_new(base, c->fd, EV_READ | EV_WRITE, redisLibeventHandler, e);
+    e->base = base;
+    return REDIS_OK;
+}
+#endif
diff --git a/tools/msys/mingw64/include/hiredis/adapters/libuv.h b/tools/msys/mingw64/include/hiredis/adapters/libuv.h
new file mode 100644
index 0000000000000000000000000000000000000000..c120b1b396bc10270a39d08d9bb78d0e63c81baa
--- /dev/null
+++ b/tools/msys/mingw64/include/hiredis/adapters/libuv.h
@@ -0,0 +1,117 @@
+#ifndef __HIREDIS_LIBUV_H__
+#define __HIREDIS_LIBUV_H__
+#include <stdlib.h>
+#include <uv.h>
+#include "../hiredis.h"
+#include "../async.h"
+#include <string.h>
+
+typedef struct redisLibuvEvents {
+  redisAsyncContext* context;
+  uv_poll_t          handle;
+  int                events;
+} redisLibuvEvents;
+
+
+static void redisLibuvPoll(uv_poll_t* handle, int status, int events) {
+  redisLibuvEvents* p = (redisLibuvEvents*)handle->data;
+  int ev = (status ? p->events : events);
+
+  if (p->context != NULL && (ev & UV_READABLE)) {
+    redisAsyncHandleRead(p->context);
+  }
+  if (p->context != NULL && (ev & UV_WRITABLE)) {
+    redisAsyncHandleWrite(p->context);
+  }
+}
+
+
+static void redisLibuvAddRead(void *privdata) {
+  redisLibuvEvents* p = (redisLibuvEvents*)privdata;
+
+  p->events |= UV_READABLE;
+
+  uv_poll_start(&p->handle, p->events, redisLibuvPoll);
+}
+
+
+static void redisLibuvDelRead(void *privdata) {
+  redisLibuvEvents* p = (redisLibuvEvents*)privdata;
+
+  p->events &= ~UV_READABLE;
+
+  if (p->events) {
+    uv_poll_start(&p->handle, p->events, redisLibuvPoll);
+  } else {
+    uv_poll_stop(&p->handle);
+  }
+}
+
+
+static void redisLibuvAddWrite(void *privdata) {
+  redisLibuvEvents* p = (redisLibuvEvents*)privdata;
+
+  p->events |= UV_WRITABLE;
+
+  uv_poll_start(&p->handle, p->events, redisLibuvPoll);
+}
+
+
+static void redisLibuvDelWrite(void *privdata) {
+  redisLibuvEvents* p = (redisLibuvEvents*)privdata;
+
+  p->events &= ~UV_WRITABLE;
+
+  if (p->events) {
+    uv_poll_start(&p->handle, p->events, redisLibuvPoll);
+  } else {
+    uv_poll_stop(&p->handle);
+  }
+}
+
+
+static void on_close(uv_handle_t* handle) {
+  redisLibuvEvents* p = (redisLibuvEvents*)handle->data;
+
+  hi_free(p);
+}
+
+
+static void redisLibuvCleanup(void *privdata) {
+  redisLibuvEvents* p = (redisLibuvEvents*)privdata;
+
+  p->context = NULL; // indicate that context might no longer exist
+  uv_close((uv_handle_t*)&p->handle, on_close);
+}
+
+
+static int redisLibuvAttach(redisAsyncContext* ac, uv_loop_t* loop) {
+  redisContext *c = &(ac->c);
+
+  if (ac->ev.data != NULL) {
+    return REDIS_ERR;
+  }
+
+  ac->ev.addRead  = redisLibuvAddRead;
+  ac->ev.delRead  = redisLibuvDelRead;
+  ac->ev.addWrite = redisLibuvAddWrite;
+  ac->ev.delWrite = redisLibuvDelWrite;
+  ac->ev.cleanup  = redisLibuvCleanup;
+
+  redisLibuvEvents* p = (redisLibuvEvents*)hi_malloc(sizeof(*p));
+  if (p == NULL)
+      return REDIS_ERR;
+
+  memset(p, 0, sizeof(*p));
+
+  if (uv_poll_init_socket(loop, &p->handle, c->fd) != 0) {
+    return REDIS_ERR;
+  }
+
+  ac->ev.data    = p;
+  p->handle.data = p;
+  p->context     = ac;
+
+  return REDIS_OK;
+}
+#endif
diff --git a/tools/msys/mingw64/include/hiredis/adapters/macosx.h b/tools/msys/mingw64/include/hiredis/adapters/macosx.h
new file mode 100644
index 0000000000000000000000000000000000000000..3c87f1b2faafafcdae4b857003dd43dcf53e63be
--- /dev/null
+++ b/tools/msys/mingw64/include/hiredis/adapters/macosx.h
@@ -0,0 +1,115 @@
+//
+//  Created by Дмитрий Бахвалов on 13.07.15.
+//  Copyright (c) 2015 Dmitry Bakhvalov. All rights reserved.
+//
+
+#ifndef __HIREDIS_MACOSX_H__
+#define __HIREDIS_MACOSX_H__
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include "../hiredis.h"
+#include "../async.h"
+
+typedef struct {
+    redisAsyncContext *context;
+    CFSocketRef socketRef;
+    CFRunLoopSourceRef sourceRef;
+} RedisRunLoop;
+
+static int freeRedisRunLoop(RedisRunLoop* redisRunLoop) {
+    if( redisRunLoop != NULL ) {
+        if( redisRunLoop->sourceRef != NULL ) {
+            CFRunLoopSourceInvalidate(redisRunLoop->sourceRef);
+            CFRelease(redisRunLoop->sourceRef);
+        }
+        if( redisRunLoop->socketRef != NULL ) {
+            CFSocketInvalidate(redisRunLoop->socketRef);
+            CFRelease(redisRunLoop->socketRef);
+        }
+        hi_free(redisRunLoop);
+    }
+    return REDIS_ERR;
+}
+
+static void redisMacOSAddRead(void *privdata) {
+    RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
+    CFSocketEnableCallBacks(redisRunLoop->socketRef, kCFSocketReadCallBack);
+}
+
+static void redisMacOSDelRead(void *privdata) {
+    RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
+    CFSocketDisableCallBacks(redisRunLoop->socketRef, kCFSocketReadCallBack);
+}
+
+static void redisMacOSAddWrite(void *privdata) {
+    RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
+    CFSocketEnableCallBacks(redisRunLoop->socketRef, kCFSocketWriteCallBack);
+}
+
+static void redisMacOSDelWrite(void *privdata) {
+    RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
+    CFSocketDisableCallBacks(redisRunLoop->socketRef, kCFSocketWriteCallBack);
+}
+
+static void redisMacOSCleanup(void *privdata) {
+    RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
+    freeRedisRunLoop(redisRunLoop);
+}
+
+static void redisMacOSAsyncCallback(CFSocketRef __unused s, CFSocketCallBackType callbackType, CFDataRef __unused address, const void __unused *data, void *info) {
+    redisAsyncContext* context = (redisAsyncContext*) info;
+
+    switch (callbackType) {
+        case kCFSocketReadCallBack:
+            redisAsyncHandleRead(context);
+            break;
+
+        case kCFSocketWriteCallBack:
+            redisAsyncHandleWrite(context);
+            break;
+
+        default:
+            break;
+    }
+}
+
+static int redisMacOSAttach(redisAsyncContext *redisAsyncCtx, CFRunLoopRef runLoop) {
+    redisContext *redisCtx = &(redisAsyncCtx->c);
+
+    /* Nothing should be attached when something is already attached */
+    if( redisAsyncCtx->ev.data != NULL ) return REDIS_ERR;
+
+    RedisRunLoop* redisRunLoop = (RedisRunLoop*) hi_calloc(1, sizeof(RedisRunLoop));
+    if (redisRunLoop == NULL)
+        return REDIS_ERR;
+
+    /* Setup redis stuff */
+    redisRunLoop->context = redisAsyncCtx;
+
+    redisAsyncCtx->ev.addRead  = redisMacOSAddRead;
+    redisAsyncCtx->ev.delRead  = redisMacOSDelRead;
+    redisAsyncCtx->ev.addWrite = redisMacOSAddWrite;
+    redisAsyncCtx->ev.delWrite = redisMacOSDelWrite;
+    redisAsyncCtx->ev.cleanup  = redisMacOSCleanup;
+    redisAsyncCtx->ev.data     = redisRunLoop;
+
+    /* Initialize and install read/write events */
+    CFSocketContext socketCtx = { 0, redisAsyncCtx, NULL, NULL, NULL };
+
+    redisRunLoop->socketRef = CFSocketCreateWithNative(NULL, redisCtx->fd,
+                                                       kCFSocketReadCallBack | kCFSocketWriteCallBack,
+                                                       redisMacOSAsyncCallback,
+                                                       &socketCtx);
+    if( !redisRunLoop->socketRef ) return freeRedisRunLoop(redisRunLoop);
+
+    redisRunLoop->sourceRef = CFSocketCreateRunLoopSource(NULL, redisRunLoop->socketRef, 0);
+    if( !redisRunLoop->sourceRef ) return freeRedisRunLoop(redisRunLoop);
+
+    CFRunLoopAddSource(runLoop, redisRunLoop->sourceRef, kCFRunLoopDefaultMode);
+
+    return REDIS_OK;
+}
+
+#endif
+
diff --git a/tools/msys/mingw64/include/hiredis/adapters/qt.h b/tools/msys/mingw64/include/hiredis/adapters/qt.h
new file mode 100644
index 0000000000000000000000000000000000000000..5cc02e6ce5ee9bda81344fba5214db17d30cf307
--- /dev/null
+++ b/tools/msys/mingw64/include/hiredis/adapters/qt.h
@@ -0,0 +1,135 @@
+/*-
+ * Copyright (C) 2014 Pietro Cerutti <gahr@gahr.ch>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __HIREDIS_QT_H__
+#define __HIREDIS_QT_H__
+#include <QSocketNotifier>
+#include "../async.h"
+
+static void RedisQtAddRead(void *);
+static void RedisQtDelRead(void *);
+static void RedisQtAddWrite(void *);
+static void RedisQtDelWrite(void *);
+static void RedisQtCleanup(void *);
+
+class RedisQtAdapter : public QObject {
+
+    Q_OBJECT
+
+    friend
+    void RedisQtAddRead(void * adapter) {
+        RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter);
+        a->addRead();
+    }
+
+    friend
+    void RedisQtDelRead(void * adapter) {
+        RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter);
+        a->delRead();
+    }
+
+    friend
+    void RedisQtAddWrite(void * adapter) {
+        RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter);
+        a->addWrite();
+    }
+
+    friend
+    void RedisQtDelWrite(void * adapter) {
+        RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter);
+        a->delWrite();
+    }
+
+    friend
+    void RedisQtCleanup(void * adapter) {
+        RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter);
+        a->cleanup();
+    }
+
+    public:
+        RedisQtAdapter(QObject * parent = 0)
+            : QObject(parent), m_ctx(0), m_read(0), m_write(0) { }
+
+        ~RedisQtAdapter() {
+            if (m_ctx != 0) {
+                m_ctx->ev.data = NULL;
+            }
+        }
+
+        int setContext(redisAsyncContext * ac) {
+            if (ac->ev.data != NULL) {
+                return REDIS_ERR;
+            }
+            m_ctx = ac;
+            m_ctx->ev.data = this;
+            m_ctx->ev.addRead = RedisQtAddRead;
+            m_ctx->ev.delRead = RedisQtDelRead;
+            m_ctx->ev.addWrite = RedisQtAddWrite;
+            m_ctx->ev.delWrite = RedisQtDelWrite;
+            m_ctx->ev.cleanup = RedisQtCleanup;
+            return REDIS_OK;
+        }
+
+    private:
+        void addRead() {
+            if (m_read) return;
+            m_read = new QSocketNotifier(m_ctx->c.fd, QSocketNotifier::Read, 0);
+            connect(m_read, SIGNAL(activated(int)), this, SLOT(read()));
+        }
+
+        void delRead() {
+            if (!m_read) return;
+            delete m_read;
+            m_read = 0;
+        }
+
+        void addWrite() {
+            if (m_write) return;
+            m_write = new QSocketNotifier(m_ctx->c.fd, QSocketNotifier::Write, 0);
+            connect(m_write, SIGNAL(activated(int)), this, SLOT(write()));
+        }
+
+        void delWrite() {
+            if (!m_write) return;
+            delete m_write;
+            m_write = 0;
+        }
+
+        void cleanup() {
+            delRead();
+            delWrite();
+        }
+
+    private slots:
+        void read() { redisAsyncHandleRead(m_ctx); }
+        void write() { redisAsyncHandleWrite(m_ctx); }
+
+    private:
+        redisAsyncContext * m_ctx;
+        QSocketNotifier * m_read;
+        QSocketNotifier * m_write;
+};
+
+#endif /* !__HIREDIS_QT_H__ */
diff --git a/tools/msys/mingw64/include/hiredis/alloc.h b/tools/msys/mingw64/include/hiredis/alloc.h
new file mode 100644
index 0000000000000000000000000000000000000000..34a05f49f3161e345292ca59e5dfd0ff8b2f4937
--- /dev/null
+++ b/tools/msys/mingw64/include/hiredis/alloc.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2020, Michael Grunder <michael dot grunder at gmail dot com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of Redis nor the names of its contributors may be used
+ *     to endorse or promote products derived from this software without
+ *     specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HIREDIS_ALLOC_H
+#define HIREDIS_ALLOC_H
+
+#include <stddef.h> /* for size_t */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Structure pointing to our actually configured allocators */
+typedef struct hiredisAllocFuncs {
+    void *(*mallocFn)(size_t);
+    void *(*callocFn)(size_t,size_t);
+    void *(*reallocFn)(void*,size_t);
+    char *(*strdupFn)(const char*);
+    void (*freeFn)(void*);
+} hiredisAllocFuncs;
+
+hiredisAllocFuncs hiredisSetAllocators(hiredisAllocFuncs *ha);
+void hiredisResetAllocators(void);
+
+#ifndef _WIN32
+
+/* Hiredis' configured allocator function pointer struct */
+extern hiredisAllocFuncs hiredisAllocFns;
+
+static inline void *hi_malloc(size_t size) {
+    return hiredisAllocFns.mallocFn(size);
+}
+
+static inline void *hi_calloc(size_t nmemb, size_t size) {
+    return hiredisAllocFns.callocFn(nmemb, size);
+}
+
+static inline void *hi_realloc(void *ptr, size_t size) {
+    return hiredisAllocFns.reallocFn(ptr, size);
+}
+
+static inline char *hi_strdup(const char *str) {
+    return hiredisAllocFns.strdupFn(str);
+}
+
+static inline void hi_free(void *ptr) {
+    hiredisAllocFns.freeFn(ptr);
+}
+
+#else
+
+void *hi_malloc(size_t size);
+void *hi_calloc(size_t nmemb, size_t size);
+void *hi_realloc(void *ptr, size_t size);
+char *hi_strdup(const char *str);
+void hi_free(void *ptr);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HIREDIS_ALLOC_H */
diff --git a/tools/msys/mingw64/include/hiredis/async.h b/tools/msys/mingw64/include/hiredis/async.h
new file mode 100644
index 0000000000000000000000000000000000000000..b1d2cb263f9979db8416c966432e35c39909379b
--- /dev/null
+++ b/tools/msys/mingw64/include/hiredis/async.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
+ * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of Redis nor the names of its contributors may be used
+ *     to endorse or promote products derived from this software without
+ *     specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __HIREDIS_ASYNC_H
+#define __HIREDIS_ASYNC_H
+#include "hiredis.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct redisAsyncContext; /* need forward declaration of redisAsyncContext */
+struct dict; /* dictionary header is included in async.c */
+
+/* Reply callback prototype and container */
+typedef void (redisCallbackFn)(struct redisAsyncContext*, void*, void*);
+typedef struct redisCallback {
+    struct redisCallback *next; /* simple singly linked list */
+    redisCallbackFn *fn;
+    int pending_subs;
+    void *privdata;
+} redisCallback;
+
+/* List of callbacks for either regular replies or pub/sub */
+typedef struct redisCallbackList {
+    redisCallback *head, *tail;
+} redisCallbackList;
+
+/* Connection callback prototypes */
+typedef void (redisDisconnectCallback)(const struct redisAsyncContext*, int status);
+typedef void (redisConnectCallback)(const struct redisAsyncContext*, int status);
+typedef void(redisTimerCallback)(void *timer, void *privdata);
+
+/* Context for an async connection to Redis */
+typedef struct redisAsyncContext {
+    /* Hold the regular context, so it can be realloc'ed. */
+    redisContext c;
+
+    /* Setup error flags so they can be used directly. */
+    int err;
+    char *errstr;
+
+    /* Not used by hiredis */
+    void *data;
+    void (*dataCleanup)(void *privdata);
+
+    /* Event library data and hooks */
+    struct {
+        void *data;
+
+        /* Hooks that are called when the library expects to start
+         * reading/writing. These functions should be idempotent. */
+        void (*addRead)(void *privdata);
+        void (*delRead)(void *privdata);
+        void (*addWrite)(void *privdata);
+        void (*delWrite)(void *privdata);
+        void (*cleanup)(void *privdata);
+        void (*scheduleTimer)(void *privdata, struct timeval tv);
+    } ev;
+
+    /* Called when either the connection is terminated due to an error or per
+     * user request. The status is set accordingly (REDIS_OK, REDIS_ERR). */
+    redisDisconnectCallback *onDisconnect;
+
+    /* Called when the first write event was received. */
+    redisConnectCallback *onConnect;
+
+    /* Regular command callbacks */
+    redisCallbackList replies;
+
+    /* Address used for connect() */
+    struct sockaddr *saddr;
+    size_t addrlen;
+
+    /* Subscription callbacks */
+    struct {
+        redisCallbackList invalid;
+        struct dict *channels;
+        struct dict *patterns;
+    } sub;
+
+    /* Any configured RESP3 PUSH handler */
+    redisAsyncPushFn *push_cb;
+} redisAsyncContext;
+
+/* Functions that proxy to hiredis */
+redisAsyncContext *redisAsyncConnectWithOptions(const redisOptions *options);
+redisAsyncContext *redisAsyncConnect(const char *ip, int port);
+redisAsyncContext *redisAsyncConnectBind(const char *ip, int port, const char *source_addr);
+redisAsyncContext *redisAsyncConnectBindWithReuse(const char *ip, int port,
+                                                  const char *source_addr);
+redisAsyncContext *redisAsyncConnectUnix(const char *path);
+int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn);
+int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn);
+
+redisAsyncPushFn *redisAsyncSetPushCallback(redisAsyncContext *ac, redisAsyncPushFn *fn);
+int redisAsyncSetTimeout(redisAsyncContext *ac, struct timeval tv);
+void redisAsyncDisconnect(redisAsyncContext *ac);
+void redisAsyncFree(redisAsyncContext *ac);
+
+/* Handle read/write events */
+void redisAsyncHandleRead(redisAsyncContext *ac);
+void redisAsyncHandleWrite(redisAsyncContext *ac);
+void redisAsyncHandleTimeout(redisAsyncContext *ac);
+void redisAsyncRead(redisAsyncContext *ac);
+void redisAsyncWrite(redisAsyncContext *ac);
+
+/* Command functions for an async context. Write the command to the
+ * output buffer and register the provided callback. */
+int redisvAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, va_list ap);
+int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, ...);
+int redisAsyncCommandArgv(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen);
+int redisAsyncFormattedCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/tools/msys/mingw64/include/hiredis/hiredis.h b/tools/msys/mingw64/include/hiredis/hiredis.h
new file mode 100644
index 0000000000000000000000000000000000000000..0622aaab8d60b02f8ef64f3062d30f99b1a6b3ff
--- /dev/null
+++ b/tools/msys/mingw64/include/hiredis/hiredis.h
@@ -0,0 +1,336 @@
+/*
+ * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
+ * Copyright (c) 2010-2014, Pieter Noordhuis <pcnoordhuis at gmail dot com>
+ * Copyright (c) 2015, Matt Stancliff <matt at genges dot com>,
+ *                     Jan-Erik Rediger <janerik at fnordig dot com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of Redis nor the names of its contributors may be used
+ *     to endorse or promote products derived from this software without
+ *     specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __HIREDIS_H
+#define __HIREDIS_H
+#include "read.h"
+#include <stdarg.h> /* for va_list */
+#ifndef _MSC_VER
+#include <sys/time.h> /* for struct timeval */
+#else
+struct timeval; /* forward declaration */
+typedef long long ssize_t;
+#endif
+#include <stdint.h> /* uintXX_t, etc */
+#include "sds.h" /* for sds */
+#include "alloc.h" /* for allocation wrappers */
+
+#define HIREDIS_MAJOR 1
+#define HIREDIS_MINOR 0
+#define HIREDIS_PATCH 0
+#define HIREDIS_SONAME 1.0.0
+
+/* Connection type can be blocking or non-blocking and is set in the
+ * least significant bit of the flags field in redisContext. */
+#define REDIS_BLOCK 0x1
+
+/* Connection may be disconnected before being free'd. The second bit
+ * in the flags field is set when the context is connected. */
+#define REDIS_CONNECTED 0x2
+
+/* The async API might try to disconnect cleanly and flush the output
+ * buffer and read all subsequent replies before disconnecting.
+ * This flag means no new commands can come in and the connection
+ * should be terminated once all replies have been read. */
+#define REDIS_DISCONNECTING 0x4
+
+/* Flag specific to the async API which means that the context should be clean
+ * up as soon as possible. */
+#define REDIS_FREEING 0x8
+
+/* Flag that is set when an async callback is executed. */
+#define REDIS_IN_CALLBACK 0x10
+
+/* Flag that is set when the async context has one or more subscriptions. */
+#define REDIS_SUBSCRIBED 0x20
+
+/* Flag that is set when monitor mode is active */
+#define REDIS_MONITORING 0x40
+
+/* Flag that is set when we should set SO_REUSEADDR before calling bind() */
+#define REDIS_REUSEADDR 0x80
+
+/**
+ * Flag that indicates the user does not want the context to
+ * be automatically freed upon error
+ */
+#define REDIS_NO_AUTO_FREE 0x200
+
+#define REDIS_KEEPALIVE_INTERVAL 15 /* seconds */
+
+/* number of times we retry to connect in the case of EADDRNOTAVAIL and
+ * SO_REUSEADDR is being used. */
+#define REDIS_CONNECT_RETRIES  10
+
+/* Forward declarations for structs defined elsewhere */
+struct redisAsyncContext;
+struct redisContext;
+
+/* RESP3 push helpers and callback prototypes */
+#define redisIsPushReply(r) (((redisReply*)(r))->type == REDIS_REPLY_PUSH)
+typedef void (redisPushFn)(void *, void *);
+typedef void (redisAsyncPushFn)(struct redisAsyncContext *, void *);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* This is the reply object returned by redisCommand() */
+typedef struct redisReply {
+    int type; /* REDIS_REPLY_* */
+    long long integer; /* The integer when type is REDIS_REPLY_INTEGER */
+    double dval; /* The double when type is REDIS_REPLY_DOUBLE */
+    size_t len; /* Length of string */
+    char *str; /* Used for REDIS_REPLY_ERROR, REDIS_REPLY_STRING
+                  REDIS_REPLY_VERB, and REDIS_REPLY_DOUBLE (in additional to dval). */
+    char vtype[4]; /* Used for REDIS_REPLY_VERB, contains the null
+                      terminated 3 character content type, such as "txt". */
+    size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */
+    struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */
+} redisReply;
+
+redisReader *redisReaderCreate(void);
+
+/* Function to free the reply objects hiredis returns by default. */
+void freeReplyObject(void *reply);
+
+/* Functions to format a command according to the protocol. */
+int redisvFormatCommand(char **target, const char *format, va_list ap);
+int redisFormatCommand(char **target, const char *format, ...);
+int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen);
+int redisFormatSdsCommandArgv(sds *target, int argc, const char ** argv, const size_t *argvlen);
+void redisFreeCommand(char *cmd);
+void redisFreeSdsCommand(sds cmd);
+
+enum redisConnectionType {
+    REDIS_CONN_TCP,
+    REDIS_CONN_UNIX,
+    REDIS_CONN_USERFD
+};
+
+struct redisSsl;
+
+#define REDIS_OPT_NONBLOCK 0x01
+#define REDIS_OPT_REUSEADDR 0x02
+
+/**
+ * Don't automatically free the async object on a connection failure,
+ * or other implicit conditions. Only free on an explicit call to disconnect() or free()
+ */
+#define REDIS_OPT_NOAUTOFREE 0x04
+
+/* Don't automatically intercept and free RESP3 PUSH replies. */
+#define REDIS_OPT_NO_PUSH_AUTOFREE 0x08
+
+/* In Unix systems a file descriptor is a regular signed int, with -1
+ * representing an invalid descriptor. In Windows it is a SOCKET
+ * (32- or 64-bit unsigned integer depending on the architecture), where
+ * all bits set (~0) is INVALID_SOCKET.  */
+#ifndef _WIN32
+typedef int redisFD;
+#define REDIS_INVALID_FD -1
+#else
+#ifdef _WIN64
+typedef unsigned long long redisFD; /* SOCKET = 64-bit UINT_PTR */
+#else
+typedef unsigned long redisFD;      /* SOCKET = 32-bit UINT_PTR */
+#endif
+#define REDIS_INVALID_FD ((redisFD)(~0)) /* INVALID_SOCKET */
+#endif
+
+typedef struct {
+    /*
+     * the type of connection to use. This also indicates which
+     * `endpoint` member field to use
+     */
+    int type;
+    /* bit field of REDIS_OPT_xxx */
+    int options;
+    /* timeout value for connect operation. If NULL, no timeout is used */
+    const struct timeval *connect_timeout;
+    /* timeout value for commands. If NULL, no timeout is used.  This can be
+     * updated at runtime with redisSetTimeout/redisAsyncSetTimeout. */
+    const struct timeval *command_timeout;
+    union {
+        /** use this field for tcp/ip connections */
+        struct {
+            const char *source_addr;
+            const char *ip;
+            int port;
+        } tcp;
+        /** use this field for unix domain sockets */
+        const char *unix_socket;
+        /**
+         * use this field to have hiredis operate an already-open
+         * file descriptor */
+        redisFD fd;
+    } endpoint;
+
+    /* Optional user defined data/destructor */
+    void *privdata;
+    void (*free_privdata)(void *);
+
+    /* A user defined PUSH message callback */
+    redisPushFn *push_cb;
+    redisAsyncPushFn *async_push_cb;
+} redisOptions;
+
+/**
+ * Helper macros to initialize options to their specified fields.
+ */
+#define REDIS_OPTIONS_SET_TCP(opts, ip_, port_) \
+    (opts)->type = REDIS_CONN_TCP; \
+    (opts)->endpoint.tcp.ip = ip_; \
+    (opts)->endpoint.tcp.port = port_;
+
+#define REDIS_OPTIONS_SET_UNIX(opts, path) \
+    (opts)->type = REDIS_CONN_UNIX;        \
+    (opts)->endpoint.unix_socket = path;
+
+#define REDIS_OPTIONS_SET_PRIVDATA(opts, data, dtor) \
+    (opts)->privdata = data;                         \
+    (opts)->free_privdata = dtor;                    \
+
+typedef struct redisContextFuncs {
+    void (*free_privctx)(void *);
+    void (*async_read)(struct redisAsyncContext *);
+    void (*async_write)(struct redisAsyncContext *);
+    ssize_t (*read)(struct redisContext *, char *, size_t);
+    ssize_t (*write)(struct redisContext *);
+} redisContextFuncs;
+
+/* Context for a connection to Redis */
+typedef struct redisContext {
+    const redisContextFuncs *funcs;   /* Function table */
+
+    int err; /* Error flags, 0 when there is no error */
+    char errstr[128]; /* String representation of error when applicable */
+    redisFD fd;
+    int flags;
+    char *obuf; /* Write buffer */
+    redisReader *reader; /* Protocol reader */
+
+    enum redisConnectionType connection_type;
+    struct timeval *connect_timeout;
+    struct timeval *command_timeout;
+
+    struct {
+        char *host;
+        char *source_addr;
+        int port;
+    } tcp;
+
+    struct {
+        char *path;
+    } unix_sock;
+
+    /* For non-blocking connect */
+    struct sockadr *saddr;
+    size_t addrlen;
+
+    /* Optional data and corresponding destructor users can use to provide
+     * context to a given redisContext.  Not used by hiredis. */
+    void *privdata;
+    void (*free_privdata)(void *);
+
+    /* Internal context pointer presently used by hiredis to manage
+     * SSL connections. */
+    void *privctx;
+
+    /* An optional RESP3 PUSH handler */
+    redisPushFn *push_cb;
+} redisContext;
+
+redisContext *redisConnectWithOptions(const redisOptions *options);
+redisContext *redisConnect(const char *ip, int port);
+redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv);
+redisContext *redisConnectNonBlock(const char *ip, int port);
+redisContext *redisConnectBindNonBlock(const char *ip, int port,
+                                       const char *source_addr);
+redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port,
+                                                const char *source_addr);
+redisContext *redisConnectUnix(const char *path);
+redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv);
+redisContext *redisConnectUnixNonBlock(const char *path);
+redisContext *redisConnectFd(redisFD fd);
+
+/**
+ * Reconnect the given context using the saved information.
+ *
+ * This re-uses the exact same connect options as in the initial connection.
+ * host, ip (or path), timeout and bind address are reused,
+ * flags are used unmodified from the existing context.
+ *
+ * Returns REDIS_OK on successful connect or REDIS_ERR otherwise.
+ */
+int redisReconnect(redisContext *c);
+
+redisPushFn *redisSetPushCallback(redisContext *c, redisPushFn *fn);
+int redisSetTimeout(redisContext *c, const struct timeval tv);
+int redisEnableKeepAlive(redisContext *c);
+void redisFree(redisContext *c);
+redisFD redisFreeKeepFd(redisContext *c);
+int redisBufferRead(redisContext *c);
+int redisBufferWrite(redisContext *c, int *done);
+
+/* In a blocking context, this function first checks if there are unconsumed
+ * replies to return and returns one if so. Otherwise, it flushes the output
+ * buffer to the socket and reads until it has a reply. In a non-blocking
+ * context, it will return unconsumed replies until there are no more. */
+int redisGetReply(redisContext *c, void **reply);
+int redisGetReplyFromReader(redisContext *c, void **reply);
+
+/* Write a formatted command to the output buffer. Use these functions in blocking mode
+ * to get a pipeline of commands. */
+int redisAppendFormattedCommand(redisContext *c, const char *cmd, size_t len);
+
+/* Write a command to the output buffer. Use these functions in blocking mode
+ * to get a pipeline of commands. */
+int redisvAppendCommand(redisContext *c, const char *format, va_list ap);
+int redisAppendCommand(redisContext *c, const char *format, ...);
+int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
+
+/* Issue a command to Redis. In a blocking context, it is identical to calling
+ * redisAppendCommand, followed by redisGetReply. The function will return
+ * NULL if there was an error in performing the request, otherwise it will
+ * return the reply. In a non-blocking context, it is identical to calling
+ * only redisAppendCommand and will always return NULL. */
+void *redisvCommand(redisContext *c, const char *format, va_list ap);
+void *redisCommand(redisContext *c, const char *format, ...);
+void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/tools/msys/mingw64/include/hiredis/hiredis_ssl.h b/tools/msys/mingw64/include/hiredis/hiredis_ssl.h
new file mode 100644
index 0000000000000000000000000000000000000000..604efe0c10dd7d0c720db5c28dee15933a30252b
--- /dev/null
+++ b/tools/msys/mingw64/include/hiredis/hiredis_ssl.h
@@ -0,0 +1,127 @@
+
+/*
+ * Copyright (c) 2019, Redis Labs
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of Redis nor the names of its contributors may be used
+ *     to endorse or promote products derived from this software without
+ *     specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __HIREDIS_SSL_H
+#define __HIREDIS_SSL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* This is the underlying struct for SSL in ssl.h, which is not included to
+ * keep build dependencies short here.
+ */
+struct ssl_st;
+
+/* A wrapper around OpenSSL SSL_CTX to allow easy SSL use without directly
+ * calling OpenSSL.
+ */
+typedef struct redisSSLContext redisSSLContext;
+
+/**
+ * Initialization errors that redisCreateSSLContext() may return.
+ */
+
+typedef enum {
+    REDIS_SSL_CTX_NONE = 0,                     /* No Error */
+    REDIS_SSL_CTX_CREATE_FAILED,                /* Failed to create OpenSSL SSL_CTX */
+    REDIS_SSL_CTX_CERT_KEY_REQUIRED,            /* Client cert and key must both be specified or skipped */
+    REDIS_SSL_CTX_CA_CERT_LOAD_FAILED,          /* Failed to load CA Certificate or CA Path */
+    REDIS_SSL_CTX_CLIENT_CERT_LOAD_FAILED,      /* Failed to load client certificate */
+    REDIS_SSL_CTX_PRIVATE_KEY_LOAD_FAILED       /* Failed to load private key */
+} redisSSLContextError;
+
+/**
+ * Return the error message corresponding with the specified error code.
+ */
+
+const char *redisSSLContextGetError(redisSSLContextError error);
+
+/**
+ * Helper function to initialize the OpenSSL library.
+ *
+ * OpenSSL requires one-time initialization before it can be used. Callers should
+ * call this function only once, and only if OpenSSL is not directly initialized
+ * elsewhere.
+ */
+int redisInitOpenSSL(void);
+
+/**
+ * Helper function to initialize an OpenSSL context that can be used
+ * to initiate SSL connections.
+ *
+ * cacert_filename is an optional name of a CA certificate/bundle file to load
+ * and use for validation.
+ *
+ * capath is an optional directory path where trusted CA certificate files are
+ * stored in an OpenSSL-compatible structure.
+ *
+ * cert_filename and private_key_filename are optional names of a client side
+ * certificate and private key files to use for authentication. They need to
+ * be both specified or omitted.
+ *
+ * server_name is an optional and will be used as a server name indication
+ * (SNI) TLS extension.
+ *
+ * If error is non-null, it will be populated in case the context creation fails
+ * (returning a NULL).
+ */
+
+redisSSLContext *redisCreateSSLContext(const char *cacert_filename, const char *capath,
+        const char *cert_filename, const char *private_key_filename,
+        const char *server_name, redisSSLContextError *error);
+
+/**
+ * Free a previously created OpenSSL context.
+ */
+void redisFreeSSLContext(redisSSLContext *redis_ssl_ctx);
+
+/**
+ * Initiate SSL on an existing redisContext.
+ *
+ * This is similar to redisInitiateSSL() but does not require the caller
+ * to directly interact with OpenSSL, and instead uses a redisSSLContext
+ * previously created using redisCreateSSLContext().
+ */
+
+int redisInitiateSSLWithContext(redisContext *c, redisSSLContext *redis_ssl_ctx);
+
+/**
+ * Initiate SSL/TLS negotiation on a provided OpenSSL SSL object.
+ */
+
+int redisInitiateSSL(redisContext *c, struct ssl_st *ssl);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* __HIREDIS_SSL_H */
diff --git a/tools/msys/mingw64/include/hiredis/read.h b/tools/msys/mingw64/include/hiredis/read.h
new file mode 100644
index 0000000000000000000000000000000000000000..2d74d77a5b41d067537587f3a34565fed4bb1da3
--- /dev/null
+++ b/tools/msys/mingw64/include/hiredis/read.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
+ * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of Redis nor the names of its contributors may be used
+ *     to endorse or promote products derived from this software without
+ *     specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef __HIREDIS_READ_H
+#define __HIREDIS_READ_H
+#include <stdio.h> /* for size_t */
+
+#define REDIS_ERR -1
+#define REDIS_OK 0
+
+/* When an error occurs, the err flag in a context is set to hold the type of
+ * error that occurred. REDIS_ERR_IO means there was an I/O error and you
+ * should use the "errno" variable to find out what is wrong.
+ * For other values, the "errstr" field will hold a description. */
+#define REDIS_ERR_IO 1 /* Error in read or write */
+#define REDIS_ERR_EOF 3 /* End of file */
+#define REDIS_ERR_PROTOCOL 4 /* Protocol error */
+#define REDIS_ERR_OOM 5 /* Out of memory */
+#define REDIS_ERR_TIMEOUT 6 /* Timed out */
+#define REDIS_ERR_OTHER 2 /* Everything else... */
+
+#define REDIS_REPLY_STRING 1
+#define REDIS_REPLY_ARRAY 2
+#define REDIS_REPLY_INTEGER 3
+#define REDIS_REPLY_NIL 4
+#define REDIS_REPLY_STATUS 5
+#define REDIS_REPLY_ERROR 6
+#define REDIS_REPLY_DOUBLE 7
+#define REDIS_REPLY_BOOL 8
+#define REDIS_REPLY_MAP 9
+#define REDIS_REPLY_SET 10
+#define REDIS_REPLY_ATTR 11
+#define REDIS_REPLY_PUSH 12
+#define REDIS_REPLY_BIGNUM 13
+#define REDIS_REPLY_VERB 14
+
+/* Default max unused reader buffer. */
+#define REDIS_READER_MAX_BUF (1024*16)
+
+/* Default multi-bulk element limit */
+#define REDIS_READER_MAX_ARRAY_ELEMENTS ((1LL<<32) - 1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct redisReadTask {
+    int type;
+    long long elements; /* number of elements in multibulk container */
+    int idx; /* index in parent (array) object */
+    void *obj; /* holds user-generated value for a read task */
+    struct redisReadTask *parent; /* parent task */
+    void *privdata; /* user-settable arbitrary field */
+} redisReadTask;
+
+typedef struct redisReplyObjectFunctions {
+    void *(*createString)(const redisReadTask*, char*, size_t);
+    void *(*createArray)(const redisReadTask*, size_t);
+    void *(*createInteger)(const redisReadTask*, long long);
+    void *(*createDouble)(const redisReadTask*, double, char*, size_t);
+    void *(*createNil)(const redisReadTask*);
+    void *(*createBool)(const redisReadTask*, int);
+    void (*freeObject)(void*);
+} redisReplyObjectFunctions;
+
+typedef struct redisReader {
+    int err; /* Error flags, 0 when there is no error */
+    char errstr[128]; /* String representation of error when applicable */
+
+    char *buf; /* Read buffer */
+    size_t pos; /* Buffer cursor */
+    size_t len; /* Buffer length */
+    size_t maxbuf; /* Max length of unused buffer */
+    long long maxelements; /* Max multi-bulk elements */
+
+    redisReadTask **task;
+    int tasks;
+
+    int ridx; /* Index of current read task */
+    void *reply; /* Temporary reply pointer */
+
+    redisReplyObjectFunctions *fn;
+    void *privdata;
+} redisReader;
+
+/* Public API for the protocol parser. */
+redisReader *redisReaderCreateWithFunctions(redisReplyObjectFunctions *fn);
+void redisReaderFree(redisReader *r);
+int redisReaderFeed(redisReader *r, const char *buf, size_t len);
+int redisReaderGetReply(redisReader *r, void **reply);
+
+#define redisReaderSetPrivdata(_r, _p) (int)(((redisReader*)(_r))->privdata = (_p))
+#define redisReaderGetObject(_r) (((redisReader*)(_r))->reply)
+#define redisReaderGetError(_r) (((redisReader*)(_r))->errstr)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/tools/msys/mingw64/include/hiredis/sds.h b/tools/msys/mingw64/include/hiredis/sds.h
new file mode 100644
index 0000000000000000000000000000000000000000..eda8833b598e883e6db1d1a6382b65a48ce0999d
--- /dev/null
+++ b/tools/msys/mingw64/include/hiredis/sds.h
@@ -0,0 +1,278 @@
+/* SDSLib 2.0 -- A C dynamic strings library
+ *
+ * Copyright (c) 2006-2015, Salvatore Sanfilippo <antirez at gmail dot com>
+ * Copyright (c) 2015, Oran Agra
+ * Copyright (c) 2015, Redis Labs, Inc
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   * Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of Redis nor the names of its contributors may be used
+ *     to endorse or promote products derived from this software without
+ *     specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __SDS_H
+#define __SDS_H
+
+#define SDS_MAX_PREALLOC (1024*1024)
+#ifdef _MSC_VER
+#define __attribute__(x)
+typedef long long ssize_t;
+#define SSIZE_MAX (LLONG_MAX >> 1)
+#endif
+
+#include <sys/types.h>
+#include <stdarg.h>
+#include <stdint.h>
+
+typedef char *sds;
+
+/* Note: sdshdr5 is never used, we just access the flags byte directly.
+ * However is here to document the layout of type 5 SDS strings. */
+struct __attribute__ ((__packed__)) sdshdr5 {
+    unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
+    char buf[];
+};
+struct __attribute__ ((__packed__)) sdshdr8 {
+    uint8_t len; /* used */
+    uint8_t alloc; /* excluding the header and null terminator */
+    unsigned char flags; /* 3 lsb of type, 5 unused bits */
+    char buf[];
+};
+struct __attribute__ ((__packed__)) sdshdr16 {
+    uint16_t len; /* used */
+    uint16_t alloc; /* excluding the header and null terminator */
+    unsigned char flags; /* 3 lsb of type, 5 unused bits */
+    char buf[];
+};
+struct __attribute__ ((__packed__)) sdshdr32 {
+    uint32_t len; /* used */
+    uint32_t alloc; /* excluding the header and null terminator */
+    unsigned char flags; /* 3 lsb of type, 5 unused bits */
+    char buf[];
+};
+struct __attribute__ ((__packed__)) sdshdr64 {
+    uint64_t len; /* used */
+    uint64_t alloc; /* excluding the header and null terminator */
+    unsigned char flags; /* 3 lsb of type, 5 unused bits */
+    char buf[];
+};
+
+#define SDS_TYPE_5  0
+#define SDS_TYPE_8  1
+#define SDS_TYPE_16 2
+#define SDS_TYPE_32 3
+#define SDS_TYPE_64 4
+#define SDS_TYPE_MASK 7
+#define SDS_TYPE_BITS 3
+#define SDS_HDR_VAR(T,s) struct sdshdr##T *sh = (struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T)));
+#define SDS_HDR(T,s) ((struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T))))
+#define SDS_TYPE_5_LEN(f) ((f)>>SDS_TYPE_BITS)
+
+static inline size_t sdslen(const sds s) {
+    unsigned char flags = s[-1];
+    switch(flags&SDS_TYPE_MASK) {
+        case SDS_TYPE_5:
+            return SDS_TYPE_5_LEN(flags);
+        case SDS_TYPE_8:
+            return SDS_HDR(8,s)->len;
+        case SDS_TYPE_16:
+            return SDS_HDR(16,s)->len;
+        case SDS_TYPE_32:
+            return SDS_HDR(32,s)->len;
+        case SDS_TYPE_64:
+            return SDS_HDR(64,s)->len;
+    }
+    return 0;
+}
+
+static inline size_t sdsavail(const sds s) {
+    unsigned char flags = s[-1];
+    switch(flags&SDS_TYPE_MASK) {
+        case SDS_TYPE_5: {
+            return 0;
+        }
+        case SDS_TYPE_8: {
+            SDS_HDR_VAR(8,s);
+            return sh->alloc - sh->len;
+        }
+        case SDS_TYPE_16: {
+            SDS_HDR_VAR(16,s);
+            return sh->alloc - sh->len;
+        }
+        case SDS_TYPE_32: {
+            SDS_HDR_VAR(32,s);
+            return sh->alloc - sh->len;
+        }
+        case SDS_TYPE_64: {
+            SDS_HDR_VAR(64,s);
+            return sh->alloc - sh->len;
+        }
+    }
+    return 0;
+}
+
+static inline void sdssetlen(sds s, size_t newlen) {
+    unsigned char flags = s[-1];
+    switch(flags&SDS_TYPE_MASK) {
+        case SDS_TYPE_5:
+            {
+                unsigned char *fp = ((unsigned char*)s)-1;
+                *fp = (unsigned char)(SDS_TYPE_5 | (newlen << SDS_TYPE_BITS));
+            }
+            break;
+        case SDS_TYPE_8:
+            SDS_HDR(8,s)->len = (uint8_t)newlen;
+            break;
+        case SDS_TYPE_16:
+            SDS_HDR(16,s)->len = (uint16_t)newlen;
+            break;
+        case SDS_TYPE_32:
+            SDS_HDR(32,s)->len = (uint32_t)newlen;
+            break;
+        case SDS_TYPE_64:
+            SDS_HDR(64,s)->len = (uint64_t)newlen;
+            break;
+    }
+}
+
+static inline void sdsinclen(sds s, size_t inc) {
+    unsigned char flags = s[-1];
+    switch(flags&SDS_TYPE_MASK) {
+        case SDS_TYPE_5:
+            {
+                unsigned char *fp = ((unsigned char*)s)-1;
+                unsigned char newlen = SDS_TYPE_5_LEN(flags)+(unsigned char)inc;
+                *fp = SDS_TYPE_5 | (newlen << SDS_TYPE_BITS);
+            }
+            break;
+        case SDS_TYPE_8:
+            SDS_HDR(8,s)->len += (uint8_t)inc;
+            break;
+        case SDS_TYPE_16:
+            SDS_HDR(16,s)->len += (uint16_t)inc;
+            break;
+        case SDS_TYPE_32:
+            SDS_HDR(32,s)->len += (uint32_t)inc;
+            break;
+        case SDS_TYPE_64:
+            SDS_HDR(64,s)->len += (uint64_t)inc;
+            break;
+    }
+}
+
+/* sdsalloc() = sdsavail() + sdslen() */
+static inline size_t sdsalloc(const sds s) {
+    unsigned char flags = s[-1];
+    switch(flags&SDS_TYPE_MASK) {
+        case SDS_TYPE_5:
+            return SDS_TYPE_5_LEN(flags);
+        case SDS_TYPE_8:
+            return SDS_HDR(8,s)->alloc;
+        case SDS_TYPE_16:
+            return SDS_HDR(16,s)->alloc;
+        case SDS_TYPE_32:
+            return SDS_HDR(32,s)->alloc;
+        case SDS_TYPE_64:
+            return SDS_HDR(64,s)->alloc;
+    }
+    return 0;
+}
+
+static inline void sdssetalloc(sds s, size_t newlen) {
+    unsigned char flags = s[-1];
+    switch(flags&SDS_TYPE_MASK) {
+        case SDS_TYPE_5:
+            /* Nothing to do, this type has no total allocation info. */
+            break;
+        case SDS_TYPE_8:
+            SDS_HDR(8,s)->alloc = (uint8_t)newlen;
+            break;
+        case SDS_TYPE_16:
+            SDS_HDR(16,s)->alloc = (uint16_t)newlen;
+            break;
+        case SDS_TYPE_32:
+            SDS_HDR(32,s)->alloc = (uint32_t)newlen;
+            break;
+        case SDS_TYPE_64:
+            SDS_HDR(64,s)->alloc = (uint64_t)newlen;
+            break;
+    }
+}
+
+sds sdsnewlen(const void *init, size_t initlen);
+sds sdsnew(const char *init);
+sds sdsempty(void);
+sds sdsdup(const sds s);
+void sdsfree(sds s);
+sds sdsgrowzero(sds s, size_t len);
+sds sdscatlen(sds s, const void *t, size_t len);
+sds sdscat(sds s, const char *t);
+sds sdscatsds(sds s, const sds t);
+sds sdscpylen(sds s, const char *t, size_t len);
+sds sdscpy(sds s, const char *t);
+
+sds sdscatvprintf(sds s, const char *fmt, va_list ap);
+#ifdef __GNUC__
+sds sdscatprintf(sds s, const char *fmt, ...)
+    __attribute__((format(printf, 2, 3)));
+#else
+sds sdscatprintf(sds s, const char *fmt, ...);
+#endif
+
+sds sdscatfmt(sds s, char const *fmt, ...);
+sds sdstrim(sds s, const char *cset);
+int sdsrange(sds s, ssize_t start, ssize_t end);
+void sdsupdatelen(sds s);
+void sdsclear(sds s);
+int sdscmp(const sds s1, const sds s2);
+sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count);
+void sdsfreesplitres(sds *tokens, int count);
+void sdstolower(sds s);
+void sdstoupper(sds s);
+sds sdsfromlonglong(long long value);
+sds sdscatrepr(sds s, const char *p, size_t len);
+sds *sdssplitargs(const char *line, int *argc);
+sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen);
+sds sdsjoin(char **argv, int argc, char *sep);
+sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen);
+
+/* Low level functions exposed to the user API */
+sds sdsMakeRoomFor(sds s, size_t addlen);
+void sdsIncrLen(sds s, int incr);
+sds sdsRemoveFreeSpace(sds s);
+size_t sdsAllocSize(sds s);
+void *sdsAllocPtr(sds s);
+
+/* Export the allocator used by SDS to the program using SDS.
+ * Sometimes the program SDS is linked to, may use a different set of
+ * allocators, but may want to allocate or free things that SDS will
+ * respectively free or allocate. */
+void *sds_malloc(size_t size);
+void *sds_realloc(void *ptr, size_t size);
+void sds_free(void *ptr);
+
+#ifdef REDIS_TEST
+int sdsTest(int argc, char *argv[]);
+#endif
+
+#endif
diff --git a/tools/msys/mingw64/lib/ccache/bin/c++ b/tools/msys/mingw64/lib/ccache/bin/c++
new file mode 100644
index 0000000000000000000000000000000000000000..23c6f0274039df63e70e1bbc3b35a1488055a45d
--- /dev/null
+++ b/tools/msys/mingw64/lib/ccache/bin/c++
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+ccache /mingw64/bin/c++ "$@"
diff --git a/tools/msys/mingw64/lib/ccache/bin/cc b/tools/msys/mingw64/lib/ccache/bin/cc
new file mode 100644
index 0000000000000000000000000000000000000000..5d093b6c5c6ef471f135388a01a074fab33c30a9
--- /dev/null
+++ b/tools/msys/mingw64/lib/ccache/bin/cc
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+ccache /mingw64/bin/cc "$@"
diff --git a/tools/msys/mingw64/lib/ccache/bin/cpp b/tools/msys/mingw64/lib/ccache/bin/cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a986ed34408fa25d6fa68a7b73eb660ffc00193e
--- /dev/null
+++ b/tools/msys/mingw64/lib/ccache/bin/cpp
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+ccache /mingw64/bin/cpp "$@"
diff --git a/tools/msys/mingw64/lib/ccache/bin/g++ b/tools/msys/mingw64/lib/ccache/bin/g++
new file mode 100644
index 0000000000000000000000000000000000000000..525d3086e4b4aa98d9a6d7281290a559a22b7bbd
--- /dev/null
+++ b/tools/msys/mingw64/lib/ccache/bin/g++
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+ccache /mingw64/bin/g++ "$@"
diff --git a/tools/msys/mingw64/lib/ccache/bin/gcc b/tools/msys/mingw64/lib/ccache/bin/gcc
new file mode 100644
index 0000000000000000000000000000000000000000..539b137f6a7fcc746774d0c091f87995a938cb07
--- /dev/null
+++ b/tools/msys/mingw64/lib/ccache/bin/gcc
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+ccache /mingw64/bin/gcc "$@"
diff --git a/tools/msys/mingw64/lib/ccache/bin/x86_64-w64-mingw32-c++ b/tools/msys/mingw64/lib/ccache/bin/x86_64-w64-mingw32-c++
new file mode 100644
index 0000000000000000000000000000000000000000..3c5056ac2e549ce0d85cd8835fcf4580cdd0f0a5
--- /dev/null
+++ b/tools/msys/mingw64/lib/ccache/bin/x86_64-w64-mingw32-c++
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+ccache /mingw64/bin/x86_64-w64-mingw32-c++ "$@"
diff --git a/tools/msys/mingw64/lib/ccache/bin/x86_64-w64-mingw32-g++ b/tools/msys/mingw64/lib/ccache/bin/x86_64-w64-mingw32-g++
new file mode 100644
index 0000000000000000000000000000000000000000..511da67a03456cafeab4ad1df73b7e254689b2c4
--- /dev/null
+++ b/tools/msys/mingw64/lib/ccache/bin/x86_64-w64-mingw32-g++
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+ccache /mingw64/bin/x86_64-w64-mingw32-g++ "$@"
diff --git a/tools/msys/mingw64/lib/ccache/bin/x86_64-w64-mingw32-gcc b/tools/msys/mingw64/lib/ccache/bin/x86_64-w64-mingw32-gcc
new file mode 100644
index 0000000000000000000000000000000000000000..6e0a270c9ce73b386340a2394cf99eabe12c67f7
--- /dev/null
+++ b/tools/msys/mingw64/lib/ccache/bin/x86_64-w64-mingw32-gcc
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+ccache /mingw64/bin/x86_64-w64-mingw32-gcc "$@"
diff --git a/tools/msys/mingw64/lib/libhiredis.dll.a b/tools/msys/mingw64/lib/libhiredis.dll.a
new file mode 100644
index 0000000000000000000000000000000000000000..8d2d288e92bfa0012953c9346a919eb46bb96e6a
Binary files /dev/null and b/tools/msys/mingw64/lib/libhiredis.dll.a differ
diff --git a/tools/msys/mingw64/lib/libhiredis_ssl.dll.a b/tools/msys/mingw64/lib/libhiredis_ssl.dll.a
new file mode 100644
index 0000000000000000000000000000000000000000..02214ea3e238218da219e39e7c356746161d2928
Binary files /dev/null and b/tools/msys/mingw64/lib/libhiredis_ssl.dll.a differ
diff --git a/tools/msys/mingw64/lib/pkgconfig/hiredis.pc b/tools/msys/mingw64/lib/pkgconfig/hiredis.pc
new file mode 100644
index 0000000000000000000000000000000000000000..2897e3ec4b028cb5fffc8e308a6de2a3579c7ed3
--- /dev/null
+++ b/tools/msys/mingw64/lib/pkgconfig/hiredis.pc
@@ -0,0 +1,12 @@
+prefix=/mingw64
+install_libdir=lib
+exec_prefix=${prefix}
+libdir=${exec_prefix}/${install_libdir}
+includedir=${prefix}/include
+pkgincludedir=${includedir}/hiredis
+
+Name: hiredis
+Description: Minimalistic C client library for Redis.
+Version: 1.0.0
+Libs: -L${libdir} -lhiredis
+Cflags: -I${pkgincludedir} -D_FILE_OFFSET_BITS=64
diff --git a/tools/msys/mingw64/lib/pkgconfig/hiredis_ssl.pc b/tools/msys/mingw64/lib/pkgconfig/hiredis_ssl.pc
new file mode 100644
index 0000000000000000000000000000000000000000..d41ffcfe667dd3682b06474d8444cfeda05fa305
--- /dev/null
+++ b/tools/msys/mingw64/lib/pkgconfig/hiredis_ssl.pc
@@ -0,0 +1,12 @@
+prefix=/mingw64
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+pkgincludedir=${includedir}/hiredis
+
+Name: hiredis_ssl
+Description: SSL Support for hiredis.
+Version: 1.0.0
+Requires: hiredis
+Libs: -L${libdir} -lhiredis_ssl
+Libs.private: -lssl -lcrypto
diff --git a/tools/msys/mingw64/share/hiredis/hiredis-config.cmake b/tools/msys/mingw64/share/hiredis/hiredis-config.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..726a097ab1a8fd480ac795089cf3da0e1ed9229e
--- /dev/null
+++ b/tools/msys/mingw64/share/hiredis/hiredis-config.cmake
@@ -0,0 +1,37 @@
+
+####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() #######
+####### Any changes to this file will be overwritten by the next CMake run ####
+####### The input file was hiredis-config.cmake.in                            ########
+
+get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../" ABSOLUTE)
+
+macro(set_and_check _var _file)
+  set(${_var} "${_file}")
+  if(NOT EXISTS "${_file}")
+    message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !")
+  endif()
+endmacro()
+
+macro(check_required_components _NAME)
+  foreach(comp ${${_NAME}_FIND_COMPONENTS})
+    if(NOT ${_NAME}_${comp}_FOUND)
+      if(${_NAME}_FIND_REQUIRED_${comp})
+        set(${_NAME}_FOUND FALSE)
+      endif()
+    endif()
+  endforeach()
+endmacro()
+
+####################################################################################
+
+set_and_check(hiredis_INCLUDEDIR "${PACKAGE_PREFIX_DIR}/include")
+
+IF (NOT TARGET hiredis::hiredis)
+	INCLUDE(${CMAKE_CURRENT_LIST_DIR}/hiredis-targets.cmake)
+ENDIF()
+
+SET(hiredis_LIBRARIES hiredis::hiredis)
+SET(hiredis_INCLUDE_DIRS ${hiredis_INCLUDEDIR})
+
+check_required_components(hiredis)
+
diff --git a/tools/msys/mingw64/share/hiredis/hiredis-targets-noconfig.cmake b/tools/msys/mingw64/share/hiredis/hiredis-targets-noconfig.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..689663ef3d197695549195b887dfb63df09f9a08
--- /dev/null
+++ b/tools/msys/mingw64/share/hiredis/hiredis-targets-noconfig.cmake
@@ -0,0 +1,19 @@
+#----------------------------------------------------------------
+# Generated CMake target import file.
+#----------------------------------------------------------------
+
+# Commands may need to know the format version.
+set(CMAKE_IMPORT_FILE_VERSION 1)
+
+# Import target "hiredis::hiredis" for configuration ""
+set_property(TARGET hiredis::hiredis APPEND PROPERTY IMPORTED_CONFIGURATIONS NOCONFIG)
+set_target_properties(hiredis::hiredis PROPERTIES
+  IMPORTED_IMPLIB_NOCONFIG "${_IMPORT_PREFIX}/lib/libhiredis.dll.a"
+  IMPORTED_LOCATION_NOCONFIG "${_IMPORT_PREFIX}/bin/libhiredis.dll"
+  )
+
+list(APPEND _IMPORT_CHECK_TARGETS hiredis::hiredis )
+list(APPEND _IMPORT_CHECK_FILES_FOR_hiredis::hiredis "${_IMPORT_PREFIX}/lib/libhiredis.dll.a" "${_IMPORT_PREFIX}/bin/libhiredis.dll" )
+
+# Commands beyond this point should not need to know the version.
+set(CMAKE_IMPORT_FILE_VERSION)
diff --git a/tools/msys/mingw64/share/hiredis/hiredis-targets.cmake b/tools/msys/mingw64/share/hiredis/hiredis-targets.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..39ec3dd6e3e4b150be47c709a6a71467fd8fb943
--- /dev/null
+++ b/tools/msys/mingw64/share/hiredis/hiredis-targets.cmake
@@ -0,0 +1,93 @@
+# Generated by CMake
+
+if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.5)
+   message(FATAL_ERROR "CMake >= 2.6.0 required")
+endif()
+cmake_policy(PUSH)
+cmake_policy(VERSION 2.6...3.17)
+#----------------------------------------------------------------
+# Generated CMake target import file.
+#----------------------------------------------------------------
+
+# Commands may need to know the format version.
+set(CMAKE_IMPORT_FILE_VERSION 1)
+
+# Protect against multiple inclusion, which would fail when already imported targets are added once more.
+set(_targetsDefined)
+set(_targetsNotDefined)
+set(_expectedTargets)
+foreach(_expectedTarget hiredis::hiredis)
+  list(APPEND _expectedTargets ${_expectedTarget})
+  if(NOT TARGET ${_expectedTarget})
+    list(APPEND _targetsNotDefined ${_expectedTarget})
+  endif()
+  if(TARGET ${_expectedTarget})
+    list(APPEND _targetsDefined ${_expectedTarget})
+  endif()
+endforeach()
+if("${_targetsDefined}" STREQUAL "${_expectedTargets}")
+  unset(_targetsDefined)
+  unset(_targetsNotDefined)
+  unset(_expectedTargets)
+  set(CMAKE_IMPORT_FILE_VERSION)
+  cmake_policy(POP)
+  return()
+endif()
+if(NOT "${_targetsDefined}" STREQUAL "")
+  message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_targetsDefined}\nTargets not yet defined: ${_targetsNotDefined}\n")
+endif()
+unset(_targetsDefined)
+unset(_targetsNotDefined)
+unset(_expectedTargets)
+
+
+# Compute the installation prefix relative to this file.
+get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
+get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
+get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
+if(_IMPORT_PREFIX STREQUAL "/")
+  set(_IMPORT_PREFIX "")
+endif()
+
+# Create imported target hiredis::hiredis
+add_library(hiredis::hiredis SHARED IMPORTED)
+
+set_target_properties(hiredis::hiredis PROPERTIES
+  INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/."
+)
+
+# Load information for each installed configuration.
+get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
+file(GLOB CONFIG_FILES "${_DIR}/hiredis-targets-*.cmake")
+foreach(f ${CONFIG_FILES})
+  include(${f})
+endforeach()
+
+# Cleanup temporary variables.
+set(_IMPORT_PREFIX)
+
+# Loop over all imported files and verify that they actually exist
+foreach(target ${_IMPORT_CHECK_TARGETS} )
+  foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} )
+    if(NOT EXISTS "${file}" )
+      message(FATAL_ERROR "The imported target \"${target}\" references the file
+   \"${file}\"
+but this file does not exist.  Possible reasons include:
+* The file was deleted, renamed, or moved to another location.
+* An install or uninstall procedure did not complete successfully.
+* The installation package was faulty and contained
+   \"${CMAKE_CURRENT_LIST_FILE}\"
+but not all the files it references.
+")
+    endif()
+  endforeach()
+  unset(_IMPORT_CHECK_FILES_FOR_${target})
+endforeach()
+unset(_IMPORT_CHECK_TARGETS)
+
+# This file does not depend on other imported targets which have
+# been exported from the same project but in a separate export set.
+
+# Commands beyond this point should not need to know the version.
+set(CMAKE_IMPORT_FILE_VERSION)
+cmake_policy(POP)
diff --git a/tools/msys/mingw64/share/hiredis_ssl/hiredis_ssl-config.cmake b/tools/msys/mingw64/share/hiredis_ssl/hiredis_ssl-config.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..3f69b2968e16522cea0e0108cca66eb9994cc2b4
--- /dev/null
+++ b/tools/msys/mingw64/share/hiredis_ssl/hiredis_ssl-config.cmake
@@ -0,0 +1,37 @@
+
+####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() #######
+####### Any changes to this file will be overwritten by the next CMake run ####
+####### The input file was hiredis_ssl-config.cmake.in                            ########
+
+get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../" ABSOLUTE)
+
+macro(set_and_check _var _file)
+  set(${_var} "${_file}")
+  if(NOT EXISTS "${_file}")
+    message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !")
+  endif()
+endmacro()
+
+macro(check_required_components _NAME)
+  foreach(comp ${${_NAME}_FIND_COMPONENTS})
+    if(NOT ${_NAME}_${comp}_FOUND)
+      if(${_NAME}_FIND_REQUIRED_${comp})
+        set(${_NAME}_FOUND FALSE)
+      endif()
+    endif()
+  endforeach()
+endmacro()
+
+####################################################################################
+
+set_and_check(hiredis_ssl_INCLUDEDIR "${PACKAGE_PREFIX_DIR}/include")
+
+IF (NOT TARGET hiredis::hiredis_ssl)
+	INCLUDE(${CMAKE_CURRENT_LIST_DIR}/hiredis_ssl-targets.cmake)
+ENDIF()
+
+SET(hiredis_ssl_LIBRARIES hiredis::hiredis_ssl)
+SET(hiredis_ssl_INCLUDE_DIRS ${hiredis_ssl_INCLUDEDIR})
+
+check_required_components(hiredis_ssl)
+
diff --git a/tools/msys/mingw64/share/hiredis_ssl/hiredis_ssl-targets-noconfig.cmake b/tools/msys/mingw64/share/hiredis_ssl/hiredis_ssl-targets-noconfig.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..9eb922db60d43e724429cb0427f75dd9a31d4af4
--- /dev/null
+++ b/tools/msys/mingw64/share/hiredis_ssl/hiredis_ssl-targets-noconfig.cmake
@@ -0,0 +1,20 @@
+#----------------------------------------------------------------
+# Generated CMake target import file.
+#----------------------------------------------------------------
+
+# Commands may need to know the format version.
+set(CMAKE_IMPORT_FILE_VERSION 1)
+
+# Import target "hiredis::hiredis_ssl" for configuration ""
+set_property(TARGET hiredis::hiredis_ssl APPEND PROPERTY IMPORTED_CONFIGURATIONS NOCONFIG)
+set_target_properties(hiredis::hiredis_ssl PROPERTIES
+  IMPORTED_IMPLIB_NOCONFIG "${_IMPORT_PREFIX}/lib/libhiredis_ssl.dll.a"
+  IMPORTED_LINK_DEPENDENT_LIBRARIES_NOCONFIG "hiredis::hiredis"
+  IMPORTED_LOCATION_NOCONFIG "${_IMPORT_PREFIX}/bin/libhiredis_ssl.dll"
+  )
+
+list(APPEND _IMPORT_CHECK_TARGETS hiredis::hiredis_ssl )
+list(APPEND _IMPORT_CHECK_FILES_FOR_hiredis::hiredis_ssl "${_IMPORT_PREFIX}/lib/libhiredis_ssl.dll.a" "${_IMPORT_PREFIX}/bin/libhiredis_ssl.dll" )
+
+# Commands beyond this point should not need to know the version.
+set(CMAKE_IMPORT_FILE_VERSION)
diff --git a/tools/msys/mingw64/share/hiredis_ssl/hiredis_ssl-targets.cmake b/tools/msys/mingw64/share/hiredis_ssl/hiredis_ssl-targets.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..e033d901e2189e9fef9a657d900d1870b54183f6
--- /dev/null
+++ b/tools/msys/mingw64/share/hiredis_ssl/hiredis_ssl-targets.cmake
@@ -0,0 +1,89 @@
+# Generated by CMake
+
+if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.5)
+   message(FATAL_ERROR "CMake >= 2.6.0 required")
+endif()
+cmake_policy(PUSH)
+cmake_policy(VERSION 2.6...3.17)
+#----------------------------------------------------------------
+# Generated CMake target import file.
+#----------------------------------------------------------------
+
+# Commands may need to know the format version.
+set(CMAKE_IMPORT_FILE_VERSION 1)
+
+# Protect against multiple inclusion, which would fail when already imported targets are added once more.
+set(_targetsDefined)
+set(_targetsNotDefined)
+set(_expectedTargets)
+foreach(_expectedTarget hiredis::hiredis_ssl)
+  list(APPEND _expectedTargets ${_expectedTarget})
+  if(NOT TARGET ${_expectedTarget})
+    list(APPEND _targetsNotDefined ${_expectedTarget})
+  endif()
+  if(TARGET ${_expectedTarget})
+    list(APPEND _targetsDefined ${_expectedTarget})
+  endif()
+endforeach()
+if("${_targetsDefined}" STREQUAL "${_expectedTargets}")
+  unset(_targetsDefined)
+  unset(_targetsNotDefined)
+  unset(_expectedTargets)
+  set(CMAKE_IMPORT_FILE_VERSION)
+  cmake_policy(POP)
+  return()
+endif()
+if(NOT "${_targetsDefined}" STREQUAL "")
+  message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_targetsDefined}\nTargets not yet defined: ${_targetsNotDefined}\n")
+endif()
+unset(_targetsDefined)
+unset(_targetsNotDefined)
+unset(_expectedTargets)
+
+
+# Compute the installation prefix relative to this file.
+get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
+get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
+get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
+if(_IMPORT_PREFIX STREQUAL "/")
+  set(_IMPORT_PREFIX "")
+endif()
+
+# Create imported target hiredis::hiredis_ssl
+add_library(hiredis::hiredis_ssl SHARED IMPORTED)
+
+# Load information for each installed configuration.
+get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
+file(GLOB CONFIG_FILES "${_DIR}/hiredis_ssl-targets-*.cmake")
+foreach(f ${CONFIG_FILES})
+  include(${f})
+endforeach()
+
+# Cleanup temporary variables.
+set(_IMPORT_PREFIX)
+
+# Loop over all imported files and verify that they actually exist
+foreach(target ${_IMPORT_CHECK_TARGETS} )
+  foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} )
+    if(NOT EXISTS "${file}" )
+      message(FATAL_ERROR "The imported target \"${target}\" references the file
+   \"${file}\"
+but this file does not exist.  Possible reasons include:
+* The file was deleted, renamed, or moved to another location.
+* An install or uninstall procedure did not complete successfully.
+* The installation package was faulty and contained
+   \"${CMAKE_CURRENT_LIST_FILE}\"
+but not all the files it references.
+")
+    endif()
+  endforeach()
+  unset(_IMPORT_CHECK_FILES_FOR_${target})
+endforeach()
+unset(_IMPORT_CHECK_TARGETS)
+
+# This file does not depend on other imported targets which have
+# been exported from the same project but in a separate export set.
+
+# Commands beyond this point should not need to know the version.
+set(CMAKE_IMPORT_FILE_VERSION)
+cmake_policy(POP)
diff --git a/tools/msys/mingw64/share/man/man1/ccache.1.gz b/tools/msys/mingw64/share/man/man1/ccache.1.gz
new file mode 100644
index 0000000000000000000000000000000000000000..988645578c71dd63dcb58f25960a37f2ed99704b
Binary files /dev/null and b/tools/msys/mingw64/share/man/man1/ccache.1.gz differ
diff --git a/tools/msys/usr/bin/dos2unix.exe b/tools/msys/usr/bin/dos2unix.exe
new file mode 100644
index 0000000000000000000000000000000000000000..1b883e552adc4cf8a38a4d87dc44b28bf1115f51
Binary files /dev/null and b/tools/msys/usr/bin/dos2unix.exe differ
diff --git a/tools/msys/usr/bin/unix2dos.exe b/tools/msys/usr/bin/unix2dos.exe
new file mode 100644
index 0000000000000000000000000000000000000000..8fcdf681dfe53d45a17bccfeb38684516f0fe2d9
Binary files /dev/null and b/tools/msys/usr/bin/unix2dos.exe differ
diff --git a/tools/msys/usr/bin/unix2mac.exe b/tools/msys/usr/bin/unix2mac.exe
new file mode 100644
index 0000000000000000000000000000000000000000..8fcdf681dfe53d45a17bccfeb38684516f0fe2d9
Binary files /dev/null and b/tools/msys/usr/bin/unix2mac.exe differ
diff --git a/tools/msys/var/lib/pacman/local/mingw-w64-i686-ccache-4.5.1-1/desc b/tools/msys/var/lib/pacman/local/mingw-w64-i686-ccache-4.5.1-1/desc
new file mode 100644
index 0000000000000000000000000000000000000000..1c1e58604d055e3a3bbc7f7c4137537a6eb969cd
--- /dev/null
+++ b/tools/msys/var/lib/pacman/local/mingw-w64-i686-ccache-4.5.1-1/desc
@@ -0,0 +1,44 @@
+%NAME%
+mingw-w64-i686-ccache
+
+%VERSION%
+4.5.1-1
+
+%BASE%
+mingw-w64-ccache
+
+%DESC%
+Compiler cache that speeds up recompilation by caching previous compilations (mingw-w64)
+
+%URL%
+https://ccache.dev/
+
+%ARCH%
+any
+
+%BUILDDATE%
+1637352822
+
+%INSTALLDATE%
+1663717665
+
+%PACKAGER%
+CI (msys2-autobuild/3ae4835f/1482554892)
+
+%SIZE%
+1848510
+
+%LICENSE%
+GPL3
+
+%VALIDATION%
+none
+
+%REPLACES%
+mingw-w64-i686-ccache-git
+
+%DEPENDS%
+mingw-w64-i686-gcc-libs
+mingw-w64-i686-hiredis
+mingw-w64-i686-zstd
+
diff --git a/tools/msys/var/lib/pacman/local/mingw-w64-i686-ccache-4.5.1-1/files b/tools/msys/var/lib/pacman/local/mingw-w64-i686-ccache-4.5.1-1/files
new file mode 100644
index 0000000000000000000000000000000000000000..8ef55b0566b68c2c6a34b712ea11781d8119110a
--- /dev/null
+++ b/tools/msys/var/lib/pacman/local/mingw-w64-i686-ccache-4.5.1-1/files
@@ -0,0 +1,20 @@
+%FILES%
+mingw32/
+mingw32/bin/
+mingw32/bin/ccache.exe
+mingw32/lib/
+mingw32/lib/ccache/
+mingw32/lib/ccache/bin/
+mingw32/lib/ccache/bin/c++
+mingw32/lib/ccache/bin/cc
+mingw32/lib/ccache/bin/cpp
+mingw32/lib/ccache/bin/g++
+mingw32/lib/ccache/bin/gcc
+mingw32/lib/ccache/bin/i686-w64-mingw32-c++
+mingw32/lib/ccache/bin/i686-w64-mingw32-g++
+mingw32/lib/ccache/bin/i686-w64-mingw32-gcc
+mingw32/share/
+mingw32/share/man/
+mingw32/share/man/man1/
+mingw32/share/man/man1/ccache.1.gz
+
diff --git a/tools/msys/var/lib/pacman/local/mingw-w64-i686-ccache-4.5.1-1/mtree b/tools/msys/var/lib/pacman/local/mingw-w64-i686-ccache-4.5.1-1/mtree
new file mode 100644
index 0000000000000000000000000000000000000000..16923041d8720e27b666e2b56541b8a3f463f267
Binary files /dev/null and b/tools/msys/var/lib/pacman/local/mingw-w64-i686-ccache-4.5.1-1/mtree differ
diff --git a/tools/msys/var/lib/pacman/local/mingw-w64-i686-hiredis-1.0.0-1/desc b/tools/msys/var/lib/pacman/local/mingw-w64-i686-hiredis-1.0.0-1/desc
new file mode 100644
index 0000000000000000000000000000000000000000..a17cb9bc56c91af8ddfa8b3de63fc93ceae42b62
--- /dev/null
+++ b/tools/msys/var/lib/pacman/local/mingw-w64-i686-hiredis-1.0.0-1/desc
@@ -0,0 +1,41 @@
+%NAME%
+mingw-w64-i686-hiredis
+
+%VERSION%
+1.0.0-1
+
+%BASE%
+mingw-w64-hiredis
+
+%DESC%
+Minimalistic C client for Redis
+
+%URL%
+https://github.com/redis/hiredis
+
+%ARCH%
+any
+
+%BUILDDATE%
+1610275542
+
+%INSTALLDATE%
+1663717665
+
+%PACKAGER%
+CI (msys2-autobuild/491f3f99/475456809)
+
+%SIZE%
+357559
+
+%LICENSE%
+BSD-3-Clause License
+
+%VALIDATION%
+none
+
+%DEPENDS%
+mingw-w64-i686-gcc-libs
+mingw-w64-i686-crt
+mingw-w64-i686-openssl
+
diff --git a/tools/msys/var/lib/pacman/local/mingw-w64-i686-hiredis-1.0.0-1/files b/tools/msys/var/lib/pacman/local/mingw-w64-i686-hiredis-1.0.0-1/files
new file mode 100644
index 0000000000000000000000000000000000000000..07aba832987b1dc9e65247cfa12065c304a38ec4
--- /dev/null
+++ b/tools/msys/var/lib/pacman/local/mingw-w64-i686-hiredis-1.0.0-1/files
@@ -0,0 +1,38 @@
+%FILES%
+mingw32/
+mingw32/bin/
+mingw32/bin/libhiredis.dll
+mingw32/bin/libhiredis_ssl.dll
+mingw32/include/
+mingw32/include/hiredis/
+mingw32/include/hiredis/adapters/
+mingw32/include/hiredis/adapters/ae.h
+mingw32/include/hiredis/adapters/glib.h
+mingw32/include/hiredis/adapters/ivykis.h
+mingw32/include/hiredis/adapters/libev.h
+mingw32/include/hiredis/adapters/libevent.h
+mingw32/include/hiredis/adapters/libuv.h
+mingw32/include/hiredis/adapters/macosx.h
+mingw32/include/hiredis/adapters/qt.h
+mingw32/include/hiredis/alloc.h
+mingw32/include/hiredis/async.h
+mingw32/include/hiredis/hiredis.h
+mingw32/include/hiredis/hiredis_ssl.h
+mingw32/include/hiredis/read.h
+mingw32/include/hiredis/sds.h
+mingw32/lib/
+mingw32/lib/libhiredis.dll.a
+mingw32/lib/libhiredis_ssl.dll.a
+mingw32/lib/pkgconfig/
+mingw32/lib/pkgconfig/hiredis.pc
+mingw32/lib/pkgconfig/hiredis_ssl.pc
+mingw32/share/
+mingw32/share/hiredis/
+mingw32/share/hiredis/hiredis-config.cmake
+mingw32/share/hiredis/hiredis-targets-noconfig.cmake
+mingw32/share/hiredis/hiredis-targets.cmake
+mingw32/share/hiredis_ssl/
+mingw32/share/hiredis_ssl/hiredis_ssl-config.cmake
+mingw32/share/hiredis_ssl/hiredis_ssl-targets-noconfig.cmake
+mingw32/share/hiredis_ssl/hiredis_ssl-targets.cmake
+
diff --git a/tools/msys/var/lib/pacman/local/mingw-w64-i686-hiredis-1.0.0-1/mtree b/tools/msys/var/lib/pacman/local/mingw-w64-i686-hiredis-1.0.0-1/mtree
new file mode 100644
index 0000000000000000000000000000000000000000..24338cad00b6157e2cc4dfc923fb65eeaa0d7108
Binary files /dev/null and b/tools/msys/var/lib/pacman/local/mingw-w64-i686-hiredis-1.0.0-1/mtree differ
diff --git a/tools/msys/var/lib/pacman/local/mingw-w64-x86_64-ccache-4.5.1-1/desc b/tools/msys/var/lib/pacman/local/mingw-w64-x86_64-ccache-4.5.1-1/desc
new file mode 100644
index 0000000000000000000000000000000000000000..3ab6710f85e84a018edecd9fff63910f72d6e0a8
--- /dev/null
+++ b/tools/msys/var/lib/pacman/local/mingw-w64-x86_64-ccache-4.5.1-1/desc
@@ -0,0 +1,44 @@
+%NAME%
+mingw-w64-x86_64-ccache
+
+%VERSION%
+4.5.1-1
+
+%BASE%
+mingw-w64-ccache
+
+%DESC%
+Compiler cache that speeds up recompilation by caching previous compilations (mingw-w64)
+
+%URL%
+https://ccache.dev/
+
+%ARCH%
+any
+
+%BUILDDATE%
+1637352876
+
+%INSTALLDATE%
+1663717666
+
+%PACKAGER%
+CI (msys2-autobuild/3ae4835f/1482554892)
+
+%SIZE%
+1650882
+
+%LICENSE%
+GPL3
+
+%VALIDATION%
+none
+
+%REPLACES%
+mingw-w64-x86_64-ccache-git
+
+%DEPENDS%
+mingw-w64-x86_64-gcc-libs
+mingw-w64-x86_64-hiredis
+mingw-w64-x86_64-zstd
+
diff --git a/tools/msys/var/lib/pacman/local/mingw-w64-x86_64-ccache-4.5.1-1/files b/tools/msys/var/lib/pacman/local/mingw-w64-x86_64-ccache-4.5.1-1/files
new file mode 100644
index 0000000000000000000000000000000000000000..47d33c810bd406876460ab732909dd472adf6d5a
--- /dev/null
+++ b/tools/msys/var/lib/pacman/local/mingw-w64-x86_64-ccache-4.5.1-1/files
@@ -0,0 +1,20 @@
+%FILES%
+mingw64/
+mingw64/bin/
+mingw64/bin/ccache.exe
+mingw64/lib/
+mingw64/lib/ccache/
+mingw64/lib/ccache/bin/
+mingw64/lib/ccache/bin/c++
+mingw64/lib/ccache/bin/cc
+mingw64/lib/ccache/bin/cpp
+mingw64/lib/ccache/bin/g++
+mingw64/lib/ccache/bin/gcc
+mingw64/lib/ccache/bin/x86_64-w64-mingw32-c++
+mingw64/lib/ccache/bin/x86_64-w64-mingw32-g++
+mingw64/lib/ccache/bin/x86_64-w64-mingw32-gcc
+mingw64/share/
+mingw64/share/man/
+mingw64/share/man/man1/
+mingw64/share/man/man1/ccache.1.gz
+
diff --git a/tools/msys/var/lib/pacman/local/mingw-w64-x86_64-ccache-4.5.1-1/mtree b/tools/msys/var/lib/pacman/local/mingw-w64-x86_64-ccache-4.5.1-1/mtree
new file mode 100644
index 0000000000000000000000000000000000000000..068923b2adc09f59665931f92b48e874a4ceb130
Binary files /dev/null and b/tools/msys/var/lib/pacman/local/mingw-w64-x86_64-ccache-4.5.1-1/mtree differ
diff --git a/tools/msys/var/lib/pacman/local/mingw-w64-x86_64-hiredis-1.0.0-1/desc b/tools/msys/var/lib/pacman/local/mingw-w64-x86_64-hiredis-1.0.0-1/desc
new file mode 100644
index 0000000000000000000000000000000000000000..d0891a5a230e71023316b43ad3a02c79e1171d59
--- /dev/null
+++ b/tools/msys/var/lib/pacman/local/mingw-w64-x86_64-hiredis-1.0.0-1/desc
@@ -0,0 +1,41 @@
+%NAME%
+mingw-w64-x86_64-hiredis
+
+%VERSION%
+1.0.0-1
+
+%BASE%
+mingw-w64-hiredis
+
+%DESC%
+Minimalistic C client for Redis
+
+%URL%
+https://github.com/redis/hiredis
+
+%ARCH%
+any
+
+%BUILDDATE%
+1610275588
+
+%INSTALLDATE%
+1663717666
+
+%PACKAGER%
+CI (msys2-autobuild/491f3f99/475456809)
+
+%SIZE%
+336583
+
+%LICENSE%
+BSD-3-Clause License
+
+%VALIDATION%
+none
+
+%DEPENDS%
+mingw-w64-x86_64-gcc-libs
+mingw-w64-x86_64-crt
+mingw-w64-x86_64-openssl
+
diff --git a/tools/msys/var/lib/pacman/local/mingw-w64-x86_64-hiredis-1.0.0-1/files b/tools/msys/var/lib/pacman/local/mingw-w64-x86_64-hiredis-1.0.0-1/files
new file mode 100644
index 0000000000000000000000000000000000000000..00eccb539aadb691e192cdd36f2d361d76304a49
--- /dev/null
+++ b/tools/msys/var/lib/pacman/local/mingw-w64-x86_64-hiredis-1.0.0-1/files
@@ -0,0 +1,38 @@
+%FILES%
+mingw64/
+mingw64/bin/
+mingw64/bin/libhiredis.dll
+mingw64/bin/libhiredis_ssl.dll
+mingw64/include/
+mingw64/include/hiredis/
+mingw64/include/hiredis/adapters/
+mingw64/include/hiredis/adapters/ae.h
+mingw64/include/hiredis/adapters/glib.h
+mingw64/include/hiredis/adapters/ivykis.h
+mingw64/include/hiredis/adapters/libev.h
+mingw64/include/hiredis/adapters/libevent.h
+mingw64/include/hiredis/adapters/libuv.h
+mingw64/include/hiredis/adapters/macosx.h
+mingw64/include/hiredis/adapters/qt.h
+mingw64/include/hiredis/alloc.h
+mingw64/include/hiredis/async.h
+mingw64/include/hiredis/hiredis.h
+mingw64/include/hiredis/hiredis_ssl.h
+mingw64/include/hiredis/read.h
+mingw64/include/hiredis/sds.h
+mingw64/lib/
+mingw64/lib/libhiredis.dll.a
+mingw64/lib/libhiredis_ssl.dll.a
+mingw64/lib/pkgconfig/
+mingw64/lib/pkgconfig/hiredis.pc
+mingw64/lib/pkgconfig/hiredis_ssl.pc
+mingw64/share/
+mingw64/share/hiredis/
+mingw64/share/hiredis/hiredis-config.cmake
+mingw64/share/hiredis/hiredis-targets-noconfig.cmake
+mingw64/share/hiredis/hiredis-targets.cmake
+mingw64/share/hiredis_ssl/
+mingw64/share/hiredis_ssl/hiredis_ssl-config.cmake
+mingw64/share/hiredis_ssl/hiredis_ssl-targets-noconfig.cmake
+mingw64/share/hiredis_ssl/hiredis_ssl-targets.cmake
+
diff --git a/tools/msys/var/lib/pacman/local/mingw-w64-x86_64-hiredis-1.0.0-1/mtree b/tools/msys/var/lib/pacman/local/mingw-w64-x86_64-hiredis-1.0.0-1/mtree
new file mode 100644
index 0000000000000000000000000000000000000000..83658779510237fa80d903348778d77dd2b33a1d
Binary files /dev/null and b/tools/msys/var/lib/pacman/local/mingw-w64-x86_64-hiredis-1.0.0-1/mtree differ
diff --git a/tools/msys/var/log/pacman.log b/tools/msys/var/log/pacman.log
index 735d9dd9b4b8f6731197f3264b11fb6f31e4c7d5..0a362f0fbe034305573fecded3e9218880c613b5 100644
--- a/tools/msys/var/log/pacman.log
+++ b/tools/msys/var/log/pacman.log
@@ -2509,3 +2509,13 @@
 [2021-06-08T10:11:41+0200] [ALPM] transaction started
 [2021-06-08T10:11:47+0200] [ALPM] installed vim (8.2.1895-1)
 [2021-06-08T10:11:47+0200] [ALPM] transaction completed
+[2022-09-21T01:45:38+0200] [PACMAN] Running 'pacman -U mingw-w64-i686-ccache-4.5.1-1-any.pkg.tar.zst'
+[2022-09-21T01:45:59+0200] [PACMAN] Running 'pacman -U mingw-w64-i686-ccache-4.5.1-1-any.pkg.tar.zst'
+[2022-09-21T01:47:18+0200] [PACMAN] Running 'pacman -U mingw-w64-i686-ccache-4.5.1-1-any.pkg.tar.zst mingw-w64-x86_64-ccache-4.5.1-1-any.pkg.tar.zst'
+[2022-09-21T01:47:42+0200] [PACMAN] Running 'pacman -U mingw-w64-i686-ccache-4.5.1-1-any.pkg.tar.zst mingw-w64-x86_64-ccache-4.5.1-1-any.pkg.tar.zst mingw-w64-i686-hiredis-1.0.0-1-any.pkg.tar.zst mingw-w64-x86_64-hiredis-1.0.0-1-any.pkg.tar.zst'
+[2022-09-21T01:47:45+0200] [ALPM] transaction started
+[2022-09-21T01:47:45+0200] [ALPM] installed mingw-w64-i686-hiredis (1.0.0-1)
+[2022-09-21T01:47:45+0200] [ALPM] installed mingw-w64-i686-ccache (4.5.1-1)
+[2022-09-21T01:47:46+0200] [ALPM] installed mingw-w64-x86_64-hiredis (1.0.0-1)
+[2022-09-21T01:47:46+0200] [ALPM] installed mingw-w64-x86_64-ccache (4.5.1-1)
+[2022-09-21T01:47:46+0200] [ALPM] transaction completed