diff --git a/native/fileWatcher/fileWatcher3.cpp b/native/fileWatcher/fileWatcher3.cpp
new file mode 100644
index 0000000..9a0b3d8
--- /dev/null
+++ b/native/fileWatcher/fileWatcher3.cpp
@@ -0,0 +1,558 @@
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "stdafx.h"
+
+struct WatchRootInfo {
+	char driveLetter;
+	HANDLE hThread;
+	HANDLE hStopEvent;
+	bool bInitialized;
+	bool bUsed;
+	bool bFailed;
+};
+
+struct WatchRoot {
+	char *path;
+	WatchRoot *next;
+};
+
+const int ROOT_COUNT = 26;
+
+WatchRootInfo watchRootInfos[ROOT_COUNT];
+
+WatchRoot *firstWatchRoot = NULL;
+
+CRITICAL_SECTION csOutput;
+
+void NormalizeSlashes(char *path, char slash)
+{
+	for(char *p=path; *p; p++)
+		if (*p == '\\' || *p == '/') 
+			*p = slash;
+}
+
+// -- Watchable root checks ---------------------------------------------------
+
+bool IsNetworkDrive(const char *name) 
+{
+    const int BUF_SIZE = 1024;
+    char buffer[BUF_SIZE];
+    UNIVERSAL_NAME_INFO* uni = (UNIVERSAL_NAME_INFO*) buffer;
+    DWORD size = BUF_SIZE;
+
+    DWORD result = WNetGetUniversalNameA(
+        name,  // path for network resource
+        UNIVERSAL_NAME_INFO_LEVEL, // level of information
+        buffer, // name buffer
+        &size // size of buffer
+    );
+
+    return result == NO_ERROR;
+}
+
+bool IsUnwatchableFS(const char *path)
+{
+    char volumeName[MAX_PATH];
+	char fsName[MAX_PATH];
+	DWORD fsFlags;
+	DWORD maxComponentLength;
+	SetErrorMode(SEM_FAILCRITICALERRORS);
+	if (!GetVolumeInformationA(path, volumeName, MAX_PATH-1, NULL, &maxComponentLength, &fsFlags, fsName, MAX_PATH-1))
+		return false;
+	if (strcmp(fsName, "NTFS") && strcmp(fsName, "FAT") && strcmp(fsName, "FAT32"))
+		return true;
+
+    if (!strcmp(fsName, "NTFS") && maxComponentLength != 255 && !(fsFlags & FILE_SUPPORTS_REPARSE_POINTS))
+	{
+		// SAMBA reports itself as NTFS
+		return true;
+	}
+
+	return false;
+}
+
+bool IsWatchable(const char *path)
+{
+	if (IsNetworkDrive(path))
+		return false;
+	if (IsUnwatchableFS(path))
+		return false;
+	return true;
+}
+
+// -- Substed drive checks ----------------------------------------------------
+
+void PrintRemapForSubstDrive(char driveLetter) 
+{
+    const int BUF_SIZE = 1024;
+    char targetPath[BUF_SIZE];
+
+	char rootPath[8];
+	sprintf_s(rootPath, 8, "%c:", driveLetter);
+
+    DWORD result = QueryDosDeviceA(rootPath, targetPath, BUF_SIZE);
+    if (result == 0) {
+        return;
+    }
+    else 
+	{
+        if (targetPath[0] == '\\' && targetPath[1] == '?' && targetPath[2] == '?' && targetPath[3] == '\\')
+		{
+			// example path: \??\C:\jetbrains\idea
+			NormalizeSlashes(targetPath, '/');
+			printf("%c:\n%s\n", driveLetter, targetPath+4);
+		}
+    }
+}
+
+void PrintRemapForSubstDrives()
+{
+	for(int i=0; i<ROOT_COUNT; i++)
+	{
+		if (watchRootInfos [i].bUsed)
+		{
+			PrintRemapForSubstDrive(watchRootInfos [i].driveLetter);
+		}
+	}
+}
+
+// -- Mount point enumeration -------------------------------------------------
+
+const int BUFSIZE = 1024;
+
+void PrintDirectoryReparsePoint(const char *path)
+{
+	int size = strlen(path)+2;
+	char *directory = (char *) malloc(size);
+	strcpy_s(directory, size, path);
+	NormalizeSlashes(directory, '\\');
+	if (directory [strlen(directory)-1] != '\\')
+		strcat_s(directory, size, "\\");
+		
+	char volumeName[_MAX_PATH];
+	int rc = GetVolumeNameForVolumeMountPointA(directory, volumeName, sizeof(volumeName));
+	if (rc)
+	{
+		char volumePathNames[_MAX_PATH];
+		DWORD returnLength;
+		rc = GetVolumePathNamesForVolumeNameA(volumeName, volumePathNames, sizeof(volumePathNames), &returnLength);
+		if (rc)
+		{
+			char *p = volumePathNames;
+			while(*p)
+			{
+				if (_stricmp(p, directory))   // if it's not the path we've already found
+				{
+					NormalizeSlashes(directory, '/');
+					NormalizeSlashes(p, '/');
+					puts(directory);
+					puts(p);
+				}
+				p += strlen(p)+1;
+			}
+		}
+	}
+	free(directory);
+}
+
+bool PrintMountPointsForVolume(HANDLE hVol, const char* volumePath, char *Buf)
+{
+    HANDLE hPt;                  // handle for mount point scan
+    char Path[BUFSIZE];          // string buffer for mount points
+    DWORD dwSysFlags;            // flags that describe the file system
+    char FileSysNameBuf[BUFSIZE];
+
+    // Is this volume NTFS? 
+    GetVolumeInformationA(Buf, NULL, 0, NULL, NULL, &dwSysFlags, FileSysNameBuf, BUFSIZE);
+
+    // Detect support for reparse points, and therefore for volume 
+    // mount points, which are implemented using reparse points. 
+
+    if (! (dwSysFlags & FILE_SUPPORTS_REPARSE_POINTS)) {
+       return true;
+    } 
+
+    // Start processing mount points on this volume. 
+    hPt = FindFirstVolumeMountPointA(
+        Buf, // root path of volume to be scanned
+        Path, // pointer to output string
+        BUFSIZE // size of output buffer
+    );
+
+    // Shall we error out?
+    if (hPt == INVALID_HANDLE_VALUE) {
+		return GetLastError() != ERROR_ACCESS_DENIED;
+    } 
+
+    // Process the volume mount point.
+	char *buf = new char[MAX_PATH];
+    do {
+		strcpy_s(buf, MAX_PATH, volumePath);
+		strcat_s(buf, MAX_PATH, Path);
+		PrintDirectoryReparsePoint(buf);
+    } while (FindNextVolumeMountPointA(hPt, Path, BUFSIZE));
+
+    FindVolumeMountPointClose(hPt);
+	return true;
+}
+
+bool PrintMountPoints(const char *path)
+{
+	char volumeUniqueName[128];
+	BOOL res = GetVolumeNameForVolumeMountPointA(path, volumeUniqueName, 128);
+	if (!res) {
+        return false;
+    }
+   
+    char buf[BUFSIZE];            // buffer for unique volume identifiers
+    HANDLE hVol;                  // handle for the volume scan
+
+    // Open a scan for volumes.
+    hVol = FindFirstVolumeA(buf, BUFSIZE );
+
+    // Shall we error out?
+    if (hVol == INVALID_HANDLE_VALUE) {
+        return false;
+    }
+
+    bool success = true;
+	do {
+       if (!strcmp(buf, volumeUniqueName)) {
+		   success = PrintMountPointsForVolume(hVol, path, buf);
+		   if (!success) break;
+	   }
+    } while (FindNextVolumeA(hVol, buf, BUFSIZE));
+
+    FindVolumeClose(hVol);
+	return success;
+}
+
+// -- Searching for mount points in watch roots (fallback) --------------------
+
+void PrintDirectoryReparsePoints(const char *path)
+{
+	char *const buf = _strdup(path);
+	while(strchr(buf, '/'))
+	{
+		DWORD attributes = GetFileAttributesA(buf);
+		if (attributes == INVALID_FILE_ATTRIBUTES)
+			break;
+		if (attributes & FILE_ATTRIBUTE_REPARSE_POINT)
+		{
+			PrintDirectoryReparsePoint(buf);
+		}
+		char *pSlash = strrchr(buf, '/');
+		if (pSlash)
+		{
+			*pSlash = '\0';
+		}
+	}
+	free(buf);
+}
+
+// This is called if we got an ERROR_ACCESS_DENIED when trying to enumerate all mount points for volume.
+// In this case, we walk the directory tree up from each watch root, and look at each parent directory 
+// to check whether it's a reparse point.
+void PrintWatchRootReparsePoints()
+{
+	WatchRoot *pWatchRoot = firstWatchRoot;
+	while(pWatchRoot)
+	{
+		PrintDirectoryReparsePoints(pWatchRoot->path);
+		pWatchRoot = pWatchRoot->next;
+	}
+}
+
+// -- Watcher thread ----------------------------------------------------------
+
+void PrintChangeInfo(char *rootPath, FILE_NOTIFY_INFORMATION *info)
+{
+	char FileNameBuffer[_MAX_PATH];
+	int converted = WideCharToMultiByte(CP_ACP, 0, info->FileName, info->FileNameLength/sizeof(WCHAR), FileNameBuffer, _MAX_PATH-1, NULL, NULL);
+	FileNameBuffer[converted] = '\0';
+	char *command;
+	if (info->Action == FILE_ACTION_ADDED || info->Action == FILE_ACTION_RENAMED_OLD_NAME)
+	{
+		command = "CREATE";
+	}
+	else if (info->Action == FILE_ACTION_REMOVED || info->Action == FILE_ACTION_RENAMED_OLD_NAME)
+	{
+		command = "DELETE";
+	}
+	else if (info->Action == FILE_ACTION_MODIFIED)
+	{
+		command = "CHANGE";	
+	}
+	else
+	{
+		return;  // unknown command
+	}
+
+	EnterCriticalSection(&csOutput);
+	puts(command);
+	printf("%s", rootPath);
+	puts(FileNameBuffer);
+	fflush(stdout);
+	LeaveCriticalSection(&csOutput);
+}
+
+void PrintEverythingChangedUnderRoot(char *rootPath)
+{
+	EnterCriticalSection(&csOutput);
+	puts("RECDIRTY");
+	puts(rootPath);
+	fflush(stdout);
+	LeaveCriticalSection(&csOutput);
+}
+
+DWORD WINAPI WatcherThread(void *param)
+{
+	WatchRootInfo *info = (WatchRootInfo *) param;
+
+	OVERLAPPED overlapped;
+	memset(&overlapped, 0, sizeof(overlapped));
+	overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+
+	char rootPath[8];
+	sprintf_s(rootPath, 8, "%c:\\", info->driveLetter);
+	HANDLE hRootDir = CreateFileA(rootPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+		NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL);
+
+	int buffer_size = 10240;
+	char *buffer = new char[buffer_size];
+
+	HANDLE handles [2];
+	handles [0] = info->hStopEvent;
+	handles [1] = overlapped.hEvent;
+	while(true)
+	{
+		int rcDir = ReadDirectoryChangesW(hRootDir, buffer, buffer_size, TRUE, 
+			FILE_NOTIFY_CHANGE_FILE_NAME |
+			FILE_NOTIFY_CHANGE_DIR_NAME | 
+			FILE_NOTIFY_CHANGE_ATTRIBUTES | 
+			FILE_NOTIFY_CHANGE_SIZE |
+			FILE_NOTIFY_CHANGE_LAST_WRITE,
+			NULL,
+			&overlapped, 
+			NULL);
+		if (rcDir == 0)
+		{
+			info->bFailed = true;
+			break;
+		}
+
+		int rc = WaitForMultipleObjects(2, handles, FALSE, INFINITE);
+		if (rc == WAIT_OBJECT_0)
+		{
+			break;
+		}
+		if (rc == WAIT_OBJECT_0+1)
+		{
+			DWORD dwBytesReturned;
+			if(!GetOverlappedResult(hRootDir, &overlapped, &dwBytesReturned, FALSE))
+			{
+				info->bFailed = true;
+				break;
+			}
+
+			if (dwBytesReturned == 0)
+			{
+				// don't send dirty too much, everything is changed anyway
+				if (WaitForSingleObject(info->hStopEvent, 500) == WAIT_OBJECT_0)
+					break;
+
+				// Got a buffer overflow => current changes lost => send RECDIRTY on root
+				PrintEverythingChangedUnderRoot(rootPath);
+			} else {
+				FILE_NOTIFY_INFORMATION *info = (FILE_NOTIFY_INFORMATION *) buffer;
+				while(true) 
+				{
+					PrintChangeInfo(rootPath, info);
+					if (!info->NextEntryOffset)
+						break;
+					info = (FILE_NOTIFY_INFORMATION *) ((char *) info + info->NextEntryOffset);
+				}
+			}
+		}
+	}
+	CloseHandle(overlapped.hEvent);
+	CloseHandle(hRootDir);
+	delete[] buffer;
+	return 0;
+}
+
+// -- Roots update ------------------------------------------------------------
+
+void MarkAllRootsUnused()
+{
+	for(int i=0; i<ROOT_COUNT; i++)
+	{
+		watchRootInfos [i].bUsed = false;
+	}
+}
+
+void StartRoot(WatchRootInfo *info)
+{
+	info->hStopEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+	info->hThread = CreateThread(NULL, 0, &WatcherThread, info, 0, NULL);
+	info->bInitialized = true;
+}
+
+void StopRoot(WatchRootInfo *info)
+{
+	SetEvent(info->hStopEvent);
+	WaitForSingleObject(info->hThread, INFINITE);
+	CloseHandle(info->hThread);
+	CloseHandle(info->hStopEvent);
+	info->bInitialized = false;
+}
+
+void UpdateRoots()
+{
+	char infoBuffer [256];
+	strcpy_s(infoBuffer, "UNWATCHEABLE\n");
+	for(int i=0; i<ROOT_COUNT; i++)
+	{
+		if (watchRootInfos [i].bInitialized && (!watchRootInfos [i].bUsed || watchRootInfos [i].bFailed))
+		{
+			StopRoot(&watchRootInfos [i]);
+			watchRootInfos [i].bFailed = false;
+		}
+		if (watchRootInfos [i].bUsed)
+		{
+			char rootPath[8];
+			sprintf_s(rootPath, 8, "%c:\\", watchRootInfos [i].driveLetter);
+			if (!IsWatchable(rootPath))
+			{
+				strcat_s(infoBuffer, rootPath);
+				strcat_s(infoBuffer, "\n");
+				continue;
+			}
+			if (!watchRootInfos [i].bInitialized)
+			{
+				StartRoot(&watchRootInfos [i]);
+			}
+		}
+	}
+	EnterCriticalSection(&csOutput);
+	fprintf(stdout, "%s", infoBuffer);
+	puts("#\nREMAP");
+	PrintRemapForSubstDrives();
+	bool printedMountPoints = true;
+	for(int i=0; i<ROOT_COUNT; i++)
+	{
+		if (watchRootInfos [i].bUsed)
+		{
+			char rootPath[8];
+			sprintf_s(rootPath, 8, "%c:\\", watchRootInfos [i].driveLetter);
+			if (!PrintMountPoints(rootPath))
+				printedMountPoints = false;
+		}
+	}
+	if (!printedMountPoints)
+	{
+		PrintWatchRootReparsePoints();
+	}
+	puts("#");
+	fflush(stdout);
+	LeaveCriticalSection(&csOutput);
+}
+
+void AddWatchRoot(const char *path)
+{
+	WatchRoot *watchRoot = (WatchRoot *) malloc(sizeof(WatchRoot));
+	watchRoot->next = NULL;
+	watchRoot->path = _strdup(path);
+	watchRoot->next = firstWatchRoot;
+	firstWatchRoot = watchRoot;
+}
+
+void FreeWatchRootsList()
+{
+	WatchRoot *pWatchRoot = firstWatchRoot;
+	WatchRoot *pNext;
+	while(pWatchRoot)
+	{
+		pNext = pWatchRoot->next;
+		free(pWatchRoot->path);
+		free(pWatchRoot);
+		pWatchRoot=pNext;
+	}
+	firstWatchRoot = NULL;
+}
+
+// -- Main - filewatcher protocol ---------------------------------------------
+
+int _tmain(int argc, _TCHAR* argv[])
+{
+	InitializeCriticalSection(&csOutput);
+
+	for(int i=0; i<26; i++)
+	{
+		watchRootInfos [i].driveLetter = 'A' + i;
+		watchRootInfos [i].bInitialized = false;
+		watchRootInfos [i].bUsed = false;
+	}
+
+	char buffer[8192];
+	while(true)
+	{
+		if (!gets_s(buffer, sizeof(buffer)-1))
+			break;
+
+		if (!strcmp(buffer, "ROOTS"))
+		{
+			MarkAllRootsUnused();
+			FreeWatchRootsList();
+			bool failed = false;
+			while(true)
+			{
+				if (!gets_s(buffer, sizeof(buffer)-1))
+				{
+					failed = true;
+					break;
+				}
+				if (buffer [0] == '#')
+					break;
+				int driveLetterPos = 0;
+				char *pDriveLetter = buffer;
+				if (*pDriveLetter == '|')
+					pDriveLetter++;
+
+				AddWatchRoot(pDriveLetter);
+
+				_strupr_s(buffer, sizeof(buffer)-1);
+				char driveLetter = *pDriveLetter;
+				if (driveLetter >= 'A' && driveLetter <= 'Z')
+				{
+					watchRootInfos [driveLetter-'A'].bUsed = true;
+				}
+			}
+			if (failed)
+				break;
+
+			UpdateRoots();
+		}
+		if (!strcmp(buffer, "EXIT"))
+			break;
+	}
+
+	MarkAllRootsUnused();
+	UpdateRoots();
+	
+	DeleteCriticalSection(&csOutput);
+}
