diff --git a/libvirt-pmc/src/util/pmc.c b/libvirt-pmc/src/util/pmc.c
new file mode 100644
index 0000000..a279197
--- /dev/null
+++ b/libvirt-pmc/src/util/pmc.c
@@ -0,0 +1,280 @@
+#include <config.h>
+#include <stdio.h>
+
+#include "pmc.h"
+#include "datatypes.h"
+#include "virterror_internal.h"
+#include "internal.h"
+#include "util.h"
+#include "logging.h"
+
+#define MAX_NETWORK_LIST 128
+
+#define VIR_FROM_THIS VIR_FROM_NONE
+
+#define virLibPMCError(code, ...)                                \
+    virReportErrorHelper(NULL, VIR_FROM_THIS, code, __FILE__,     \
+                         __FUNCTION__, __LINE__, __VA_ARGS__)
+
+/*-------------------- various functions --------------------*/
+
+/**
+ * splitVersion
+ * 
+ * Convert (unsigned long) version provided by libvirtVersion() in array
+ * where:
+ *   array[0] = major number
+ *   array[1] = minor number
+ *   array[2] = release
+ */
+static void
+splitVersion(unsigned long ver, unsigned int *split)
+{
+    int maj = ver/1000000;
+    int min = (ver - maj*1000000)/1000;
+    int rel = ver - maj*1000000 - min*1000;
+    split[0] = maj;
+    split[1] = min;
+    split[2] = rel;
+    return;
+}
+
+/**
+ * warningMenu
+ * 
+ * Print a menù to select the action when check return value 
+ * CHECK_WARNING. The availables choise are:
+ *   T - terminate migrationt process
+ *   C - continue (at your own risk) migration process
+ */
+int
+warningMenu(void)
+{
+    char sel = 0;
+    int retval = TERMINATE;
+    
+    printf("C - continue (at your own risk) migration process\n");
+    printf("T - terminate migration process\n");
+    printf("Action [default: T]: ");
+    
+    sel = getchar();
+    
+    switch(sel)
+    {
+        case 't':
+        case 'T':
+            break;
+        case 'c':
+        case 'C':
+            retval = CONTINUE;
+            break;
+        default:
+            printf("Wrong selectopn! Migration will be terminated.\n");
+            retval = TERMINATE;
+            break;
+    }
+    
+    return retval;
+}
+
+/*-------------------- checks implementation --------------------*/
+
+/**
+ * pmcCheckVersion
+ * 
+ * Perform the comparison between local and remote libvirt version.
+ * 
+ * If libvirt version are not equals, check return CHECK_WARNING, else
+ * check return CHECK_SUCCESS.
+ * 
+ * The defined comparison algorithm is only a draft! It can be improved
+ * using a compatibility table or similar.
+ */
+
+static int
+pmcCheckVersion(virDomainPtr domain,
+                virConnectPtr dconn)
+{
+    virConnectPtr conn                = NULL;
+    unsigned long localLibVersion     = 0;
+    
+    unsigned long remoteLibVersion    = 0;
+    
+    int res                           = -1;
+    unsigned int lver[3]              = {0};
+    unsigned int rver[3]              = {0};
+    
+    virResetLastError();
+    
+    /* check params */
+    if (domain == NULL || dconn == NULL) {
+        virLibPMCError(VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto error;
+    }
+
+    /* check domain */
+    if (!VIR_IS_CONNECTED_DOMAIN (domain)) {
+        virLibPMCError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+        goto error;
+    }
+    if (domain->conn->flags & VIR_CONNECT_RO) {
+        virLibPMCError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+        goto error;
+    }
+
+    /* check remote connection */
+    if (!VIR_IS_CONNECT(dconn)) {
+        virLibPMCError(VIR_ERR_INVALID_CONN, __FUNCTION__);
+        goto error;
+    }
+    if (dconn->flags & VIR_CONNECT_RO) {
+        virLibPMCError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+        goto error;
+    }
+    
+    conn = domain->conn;
+    
+    /* get local infos */
+    
+    res = conn->driver->libvirtVersion(conn,&localLibVersion);
+    if (res < 0)
+    {
+        virLibPMCError(VIR_ERR_INTERNAL_ERROR,__FUNCTION__);
+        goto error;
+    }
+    
+    
+    /* get remote infos */
+    
+    res = dconn->driver->libvirtVersion(dconn,&remoteLibVersion);
+    if (res < 0)
+    {
+        virLibPMCError(VIR_ERR_INTERNAL_ERROR,__FUNCTION__);
+        goto error;
+    }
+    
+    /* check */
+    
+    if( localLibVersion == remoteLibVersion )
+        return CHECK_SUCCESS;
+    else
+    {
+        splitVersion(localLibVersion,lver);
+        splitVersion(remoteLibVersion,rver);
+        printf("  WARNING: local libvirt version (%d.%d.%d) is not equal to remote libvirt version (%d.%d.%d)\n",
+               lver[0],lver[1],lver[2],
+               rver[0],rver[1],rver[2]);
+        return CHECK_WARNING;
+    }
+
+error:
+    virDispatchError(domain->conn);
+    return INTERNAL_ERROR;
+}
+
+/**
+ * pmcCheckHypervisorType
+ * 
+ * Perform the comparison between hypervisor type. Check return value
+ * CHECK_SUCCESS if local and remote hypervisor type are equals, else 
+ * CHECK_FAIL.
+ * 
+ * TODO
+ * Check can be improved by adding the comparison between 
+ * hypervisor versions if local and remote type is the same.
+ */
+static int 
+pmcCheckHypervisorType(virDomainPtr domain,
+                       virConnectPtr dconn)
+{
+    virConnectPtr conn              = NULL;
+    const char *localHypervisor     = NULL;
+    const char *remoteHypervisor    = NULL;
+    
+    virResetLastError();
+    
+    /* check params */
+    if (domain == NULL || dconn == NULL) {
+        virLibPMCError(VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto error;
+    }
+
+    /* check domain */
+    if (!VIR_IS_CONNECTED_DOMAIN (domain)) {
+        virLibPMCError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+        goto error;
+    }
+    if (domain->conn->flags & VIR_CONNECT_RO) {
+        virLibPMCError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+        goto error;
+    }
+
+    /* check remote connection */
+    if (!VIR_IS_CONNECT(dconn)) {
+        virLibPMCError(VIR_ERR_INVALID_CONN, __FUNCTION__);
+        goto error;
+    }
+    
+    if (dconn->flags & VIR_CONNECT_RO) {
+        virLibPMCError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+        goto error;
+    }
+    
+    conn = domain->conn;
+    
+    /* get local hypervisor type */
+    if (conn->driver->name)
+        localHypervisor = conn->driver->name;
+    else
+    {
+        virLibPMCError(VIR_ERR_INTERNAL_ERROR,__FUNCTION__);
+        goto error;
+    }
+    
+    /* get remote hypervisor type */
+    if (dconn->driver->name)
+        remoteHypervisor = dconn->driver->name;
+    else
+    {
+        virLibPMCError(VIR_ERR_INTERNAL_ERROR,__FUNCTION__);
+        goto error;
+    }
+    
+    /* check */
+    
+    if( STRNEQ(localHypervisor,remoteHypervisor) )
+    {
+        printf("  ERROR: local hypervisor (%s) is not equal to remote hypervisor (%s)\n",
+               localHypervisor,remoteHypervisor);
+        return CHECK_FAIL;
+    }
+    
+    
+    return CHECK_SUCCESS;
+    
+error:
+    virDispatchError(domain->conn);
+    return INTERNAL_ERROR;
+}
+
+/*--------------- pre migration check interface ---------------*/
+
+static virPMCCheck chk1 = {
+    .name = "compare libvirt version",
+    .run = pmcCheckVersion
+};
+
+static virPMCCheck chk2 = {
+    .name = "compare hypervisor type",
+    .run = pmcCheckHypervisorType
+};
+
+static virPMCCheckList chklist = {
+    .count = 2,
+    .check = {&chk1,&chk2,NULL}
+};
+
+virPMCCheckListPtr virPMCGetList(void)
+{
+    return &chklist;
+}
