diff --git a/find_java2/src/FindJava2Dlg.cpp b/find_java2/src/FindJava2Dlg.cpp
new file mode 100755
index 0000000..fbdd899
--- /dev/null
+++ b/find_java2/src/FindJava2Dlg.cpp
@@ -0,0 +1,268 @@
+/*
+* Copyright (C) 2014 The Android Open Source Project
+*
+* 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"
+#include "utils.h"
+#include "FindJava2Dlg.h"
+#include "afxdialogex.h"
+#include <atlpath.h>                            // ATL CPath
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+#define COL_PATH 1
+
+
+CFindJava2Dlg::CFindJava2Dlg(CWnd* pParent /*=NULL*/)
+    : CDialog(CFindJava2Dlg::IDD, pParent), mSelectedIndex(-1) {
+    m_hIcon = AfxGetApp()->LoadIcon(IDI_ANDROID_ICON);
+}
+
+void CFindJava2Dlg::DoDataExchange(CDataExchange* pDX) {
+    CDialog::DoDataExchange(pDX);
+    DDX_Control(pDX, IDC_PATH_LIST, mPathsListCtrl);
+    DDX_Control(pDX, IDOK, mOkButton);
+}
+
+BEGIN_MESSAGE_MAP(CFindJava2Dlg, CDialog)
+    ON_WM_PAINT()
+    ON_WM_QUERYDRAGICON()
+    ON_BN_CLICKED(IDC_BUTTON_ADD, &CFindJava2Dlg::OnBnClickedButtonAdd)
+    ON_NOTIFY(NM_CLICK, IDC_PATH_LIST, &CFindJava2Dlg::OnNMClickPathList)
+    ON_NOTIFY(LVN_ITEMCHANGED, IDC_PATH_LIST, &CFindJava2Dlg::OnLvnItemchangedPathList)
+END_MESSAGE_MAP()
+
+
+// -----
+// CFindJava2Dlg message handlers
+
+BOOL CFindJava2Dlg::OnInitDialog() {
+    CDialog::OnInitDialog();
+
+    SetWindowText(getAppName());
+
+    // Set the icon for this dialog.  The framework does this automatically
+    //  when the application's main window is not a dialog
+    SetIcon(m_hIcon, TRUE);			// Set big icon
+    SetIcon(m_hIcon, FALSE);		// Set small icon
+
+    // Initialize list controls
+    mPathsListCtrl.SetExtendedStyle(
+        mPathsListCtrl.GetExtendedStyle() |
+        LVS_EX_CHECKBOXES | 
+        LVS_EX_FULLROWSELECT | 
+        LVS_EX_GRIDLINES);
+
+    // We want 2 columns: Java version and path
+    mPathsListCtrl.InsertColumn(0, _T("Version"), LVCFMT_RIGHT, 60,  0);
+    mPathsListCtrl.InsertColumn(1, _T("Path"),     LVCFMT_LEFT, 386, 0);
+
+    mJavaFinder->findJavaPaths(&mPaths);
+    fillPathsList();
+    adjustButtons();
+
+    return TRUE;  // return TRUE  unless you set the focus to a control
+}
+
+// If you add a minimize button to your dialog, you will need the code below
+// to draw the icon.  For MFC applications using the document/view model,
+// this is automatically done for you by the framework.
+// [Note: MFC boilerplate, keep as-is]
+void CFindJava2Dlg::OnPaint() {
+    if (IsIconic()) {
+        CPaintDC dc(this); // device context for painting
+
+        SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
+
+        // Center icon in client rectangle
+        int cxIcon = GetSystemMetrics(SM_CXICON);
+        int cyIcon = GetSystemMetrics(SM_CYICON);
+        CRect rect;
+        GetClientRect(&rect);
+        int x = (rect.Width() - cxIcon + 1) / 2;
+        int y = (rect.Height() - cyIcon + 1) / 2;
+
+        // Draw the icon
+        dc.DrawIcon(x, y, m_hIcon);
+    } else {
+        CDialog::OnPaint();
+    }
+}
+
+// The system calls this function to obtain the cursor to display while the user drags
+// the minimized window. [Note: MFC boilerplate, keep as-is]
+HCURSOR CFindJava2Dlg::OnQueryDragIcon() {
+    return static_cast<HCURSOR>(m_hIcon);
+}
+
+// Button add has been pressed; use file dialog and add path if it's a valid java.exe
+void CFindJava2Dlg::OnBnClickedButtonAdd() {
+    CFileDialog fileDlg(
+        TRUE,           // true=open dialog,  false=save-as dialog
+        _T("exe"),      // lpszDefExt 
+        _T("java.exe"), // lpszFileName 
+        OFN_FILEMUSTEXIST || OFN_PATHMUSTEXIST,
+        NULL,           // lpszFilter
+        this);          // pParentWnd
+
+    if (fileDlg.DoModal() == IDOK) {
+        CString path = fileDlg.GetPathName();
+
+        CJavaPath javaPath;
+        if (!mJavaFinder->checkJavaPath(path, &javaPath)) {
+            CString msg;
+            if (javaPath.mVersion > 0) {
+                msg.Format(_T("Insufficient Java Version found: expected %s, got %s"), 
+                           CJavaPath(mJavaFinder->getMinVersion(), CPath()).getVersion(),
+                           javaPath.getVersion());
+            } else {
+                msg.Format(_T("No valid Java Version found for %s"), path);
+            }
+            AfxMessageBox(msg, MB_OK);
+
+        } else {
+            if (mPaths.find(javaPath) == mPaths.end()) {
+                // Path isn't known yet so add it and refresh the list.
+                mPaths.insert(javaPath);
+                fillPathsList();
+            }
+
+            // Select item in list and set mSelectedIndex
+            selectPath(-1 /*index*/, &javaPath);
+        }
+    }
+}
+
+// An item in the list has been selected, select checkmark and set mSelectedIndex.
+void CFindJava2Dlg::OnNMClickPathList(NMHDR *pNMHDR, LRESULT *pResult) {
+    LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
+    int index = pNMItemActivate->iItem;
+    selectPath(index, nullptr);
+    *pResult = TRUE;
+}
+
+// An item in the list has changed, toggle checkmark as needed.
+void CFindJava2Dlg::OnLvnItemchangedPathList(NMHDR *pNMHDR, LRESULT *pResult) {
+    *pResult = FALSE;
+    LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
+
+    if ((pNMLV->uChanged & LVIF_STATE) != 0) {
+        // Item's state has changed. Check the selection to see if it needs to be adjusted.
+        int index = pNMLV->iItem;
+
+        UINT oldState = pNMLV->uOldState;
+        UINT newState = pNMLV->uNewState;
+
+        if ((oldState & LVIS_STATEIMAGEMASK) != 0 || (newState & LVIS_STATEIMAGEMASK) != 0) {
+            // Checkbox uses the STATEIMAGE: 1 for unchecked, 2 for checked.
+            // Checkbox is checked when (old/new-state & state-image-mask) == INDEXTOSTATEIMAGEMASK(2).
+
+            bool oldChecked = (oldState & LVIS_STATEIMAGEMASK) == INDEXTOSTATEIMAGEMASK(2);
+            bool newChecked = (newState & LVIS_STATEIMAGEMASK) == INDEXTOSTATEIMAGEMASK(2);
+
+            if (oldChecked && !newChecked && index == mSelectedIndex) {
+                mSelectedIndex = -1;
+                adjustButtons();
+            } else if (!oldChecked && newChecked && index != mSelectedIndex) {
+                // Uncheck any checked rows if any
+                for (int n = mPathsListCtrl.GetItemCount() - 1; n >= 0; --n) {
+                    if (n != index && mPathsListCtrl.GetCheck(n)) {
+                        mPathsListCtrl.SetCheck(n, FALSE);
+                    }
+                }
+
+                mSelectedIndex = index;
+                adjustButtons();
+            }
+            // We handled this case, don't dispatch it further
+            *pResult = TRUE;
+        }
+    }
+}
+
+// -----
+
+const CJavaPath& CFindJava2Dlg::getSelectedPath() {
+    int i = 0;
+    for (const CJavaPath &p : mPaths) {
+        if (i == mSelectedIndex) {
+            return p;
+        }
+        ++i;
+    }
+
+    return CJavaPath::sEmpty;
+}
+
+
+void CFindJava2Dlg::fillPathsList() {
+    mPathsListCtrl.DeleteAllItems();
+    int index = 0;
+
+    for (const CJavaPath& pv : mPaths) {
+        mPathsListCtrl.InsertItem(index, pv.getVersion());        // column 0 = version
+        mPathsListCtrl.SetItemText(index, COL_PATH, pv.mPath);    // column 1 = path
+        mPathsListCtrl.SetCheck(index, mSelectedIndex == index);
+        ++index;
+    }
+}
+
+// Checks the given index if valid. Unchecks all other items.
+//
+// If index >= 0, it is used to select that item from the ListControl.
+// Otherwise if path != nullptr, it is used to find the item and select it.
+//
+// Side effect: in both cases, mSelectedIndex is set to the matching index or -1.
+//
+// If index is invalid and path isn't in the mPaths list, all items are unselected
+// so calling this with (0, nullptr) will clear the current selection.
+void CFindJava2Dlg::selectPath(int index, const CJavaPath *path) {
+
+    const CJavaPath *foundPath;
+    // If index is not defined, find the given path in the internal list.
+    // If path is not defined, find its index in the internal list.
+    int i = 0;
+    int n = mPathsListCtrl.GetItemCount();
+    for (const CJavaPath &p : mPaths) {
+        if (index < 0 && path != nullptr && p == *path) {
+            index = i;
+            foundPath = path;
+        } else if (index == i) {
+            foundPath = &p;
+        }
+
+        // uncheck any marked path
+        if (i != index && i < n && mPathsListCtrl.GetCheck(i)) {
+            mPathsListCtrl.SetCheck(i, FALSE);
+        }
+
+        ++i;
+    }
+
+    mSelectedIndex = index;
+    if (index >= 0 && index <= n) {
+        mPathsListCtrl.SetCheck(index, TRUE);
+    }
+
+    adjustButtons();
+}
+
+void CFindJava2Dlg::adjustButtons() {
+    int n = mPathsListCtrl.GetItemCount();
+    mOkButton.EnableWindow(mSelectedIndex >= 0 && mSelectedIndex < n);
+}
diff --git a/find_java2/src/FindJava2Dlg.h b/find_java2/src/FindJava2Dlg.h
new file mode 100755
index 0000000..7e0943c
--- /dev/null
+++ b/find_java2/src/FindJava2Dlg.h
@@ -0,0 +1,64 @@
+/*
+* Copyright (C) 2014 The Android Open Source Project
+*
+* 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.
+*/
+
+#pragma once
+#include "afxwin.h"
+#include "JavaFinder.h"
+
+#include "resource.h"		// main symbols
+
+
+// CFindJava2Dlg dialog
+class CFindJava2Dlg : public CDialog {
+    // Construction
+public:
+    CFindJava2Dlg(CWnd* pParent = NULL);	// standard constructor
+
+    void setJavaFinder(CJavaFinder *javaFinder) { mJavaFinder = javaFinder;  }
+    const CJavaPath& getSelectedPath();
+
+    // Dialog Data
+    enum { IDD = IDD_FINDJAVA2_DIALOG };
+
+protected:
+    virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV support
+
+
+    // Implementation
+protected:
+    HICON m_hIcon;
+
+    // Generated message map functions
+    virtual BOOL OnInitDialog();
+    afx_msg void OnPaint();
+    afx_msg HCURSOR OnQueryDragIcon();
+    DECLARE_MESSAGE_MAP()
+
+    afx_msg void OnBnClickedButtonAdd();
+    afx_msg void OnNMClickPathList(NMHDR *pNMHDR, LRESULT *pResult);
+    afx_msg void OnLvnItemchangedPathList(NMHDR *pNMHDR, LRESULT *pResult);
+
+private:
+    std::set<CJavaPath> mPaths;
+    int mSelectedIndex;
+    CJavaFinder *mJavaFinder;
+    CListCtrl mPathsListCtrl;
+    CButton mOkButton;
+
+    void fillPathsList();
+    void adjustButtons();
+    void selectPath(int index = -1, const CJavaPath *path = nullptr);
+};
diff --git a/find_java2/src/JavaFinder.cpp b/find_java2/src/JavaFinder.cpp
new file mode 100755
index 0000000..60a2e23
--- /dev/null
+++ b/find_java2/src/JavaFinder.cpp
@@ -0,0 +1,594 @@
+/*
+* Copyright (C) 2014 The Android Open Source Project
+*
+* 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"
+#include "JavaFinder.h"
+#include "utils.h"
+
+#include <algorithm>        // std::sort and std::unique
+
+#define  _CRT_SECURE_NO_WARNINGS
+
+// --------------
+
+#define JF_REGISTRY_KEY         _T("Software\\Android\\FindJava2")
+#define JF_REGISTRY_VALUE_PATH  _T("JavaPath")
+#define JF_REGISTRY_VALUE_VERS  _T("JavaVers")
+
+// --------------
+
+
+// Extract the first thing that looks like (digit.digit+).
+// Note: this will break when java reports a version with major > 9.
+// However it will reasonably cope with "1.10", if that ever happens.
+static bool extractJavaVersion(const TCHAR *start,
+                               int length,
+                               CString *outVersionStr,
+                               int *outVersionInt) {
+    const TCHAR *end = start + length;
+    for (const TCHAR *c = start; c < end - 2; c++) {
+        if (isdigit(c[0]) &&
+            c[1] == '.' &&
+            isdigit(c[2])) {
+            const TCHAR *e = c + 2;
+            while (isdigit(e[1])) {
+                e++;
+            }
+            outVersionStr->SetString(c, e - c + 1);
+
+            // major is currently only 1 digit
+            int major = (*c - '0');
+            // add minor
+            int minor = 0;
+            for (int m = 1; *e != '.'; e--, m *= 10) {
+                minor += (*e - '0') * m;
+            }
+            *outVersionInt = JAVA_VERS_TO_INT(major, minor);
+            return true;
+        }
+    }
+    return false;
+}
+
+// Tries to invoke the java.exe at the given path and extract it's
+// version number.
+// - outVersionStr: not null, will capture version as a string (e.g. "1.6")
+// - outVersionInt: not null, will capture version as an int (see JavaPath.h).
+bool getJavaVersion(CPath &javaPath, CString *outVersionStr, int *outVersionInt) {
+    bool result = false;
+
+    // Run "java -version", which outputs something to *STDERR* like this:
+    //
+    // java version "1.6.0_29"
+    // Java(TM) SE Runtime Environment (build 1.6.0_29-b11)
+    // Java HotSpot(TM) Client VM (build 20.4-b02, mixed mode, sharing)
+    //
+    // We want to capture the first line, and more exactly the "1.6" part.
+
+
+    CString cmd;
+    cmd.Format(_T("\"%s\" -version"), (LPCTSTR) javaPath);
+
+    SECURITY_ATTRIBUTES   saAttr;
+    STARTUPINFO           startup;
+    PROCESS_INFORMATION   pinfo;
+
+    // Want to inherit pipe handle
+    ZeroMemory(&saAttr, sizeof(saAttr));
+    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
+    saAttr.bInheritHandle = TRUE;
+    saAttr.lpSecurityDescriptor = NULL;
+
+    // Create pipe for stdout
+    HANDLE stdoutPipeRd, stdoutPipeWt;
+    if (!CreatePipe(
+            &stdoutPipeRd,      // hReadPipe,
+            &stdoutPipeWt,      // hWritePipe,
+            &saAttr,            // lpPipeAttributes,
+            0)) {               // nSize (0=default buffer size)
+        // In FindJava2, we do not report these errors. Leave commented for reference.
+        // // if (gIsConsole || gIsDebug) displayLastError("CreatePipe failed: ");
+        return false;
+    }
+    if (!SetHandleInformation(stdoutPipeRd, HANDLE_FLAG_INHERIT, 0)) {
+        // In FindJava2, we do not report these errors. Leave commented for reference.
+        // // if (gIsConsole || gIsDebug) displayLastError("SetHandleInformation failed: ");
+        return false;
+    }
+
+    ZeroMemory(&pinfo, sizeof(pinfo));
+
+    ZeroMemory(&startup, sizeof(startup));
+    startup.cb = sizeof(startup);
+    startup.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
+    startup.wShowWindow = SW_HIDE | SW_MINIMIZE;
+    // Capture both stderr and stdout
+    startup.hStdError = stdoutPipeWt;
+    startup.hStdOutput = stdoutPipeWt;
+    startup.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+
+    BOOL ok = CreateProcess(
+        NULL,                   // program path
+        (LPTSTR)((LPCTSTR) cmd),// command-line
+        NULL,                   // process handle is not inheritable
+        NULL,                   // thread handle is not inheritable
+        TRUE,                   // yes, inherit some handles
+        0,                      // process creation flags
+        NULL,                   // use parent's environment block
+        NULL,                   // use parent's starting directory
+        &startup,               // startup info, i.e. std handles
+        &pinfo);
+
+    // In FindJava2, we do not report these errors. Leave commented for reference.
+    // // if ((gIsConsole || gIsDebug) && !ok) displayLastError("CreateProcess failed: ");
+
+    // Close the write-end of the output pipe (we're only reading from it)
+    CloseHandle(stdoutPipeWt);
+
+    // Read from the output pipe. We don't need to read everything,
+    // the first line should be 'Java version "1.2.3_45"\r\n'
+    // so reading about 32 chars is all we need.
+    TCHAR first32[32 + 1];
+    int index = 0;
+    first32[0] = 0;
+
+    if (ok) {
+        #define SIZE 1024
+        char buffer[SIZE];
+        DWORD sizeRead = 0;
+
+        while (ok) {
+            // Keep reading in the same buffer location
+            // Note: ReadFile uses a char buffer, not a TCHAR one.
+            ok = ReadFile(stdoutPipeRd,     // hFile
+                          buffer,           // lpBuffer
+                          SIZE,             // DWORD buffer size to read
+                          &sizeRead,        // DWORD buffer size read
+                          NULL);            // overlapped
+            if (!ok || sizeRead == 0 || sizeRead > SIZE) break;
+
+            // Copy up to the first 32 characters
+            if (index < 32) {
+                DWORD n = 32 - index;
+                if (n > sizeRead) n = sizeRead;
+                // copy as lowercase to simplify checks later
+                for (char *b = buffer; n > 0; n--, b++, index++) {
+                    char c = *b;
+                    if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
+                    first32[index] = c;
+                }
+                first32[index] = 0;
+            }
+        }
+
+        WaitForSingleObject(pinfo.hProcess, INFINITE);
+
+        DWORD exitCode;
+        if (GetExitCodeProcess(pinfo.hProcess, &exitCode)) {
+            // this should not return STILL_ACTIVE (259)
+            result = exitCode == 0;
+        }
+
+        CloseHandle(pinfo.hProcess);
+        CloseHandle(pinfo.hThread);
+    }
+    CloseHandle(stdoutPipeRd);
+
+    if (result && index > 0) {
+        // Look for a few keywords in the output however we don't
+        // care about specific ordering or case-senstiviness.
+        // We only capture roughtly the first line in lower case.
+        TCHAR *j = _tcsstr(first32, _T("java"));
+        TCHAR *v = _tcsstr(first32, _T("version"));
+        // In FindJava2, we do not report these errors. Leave commented for reference.
+        // // if ((gIsConsole || gIsDebug) && (!j || !v)) {
+        // //     fprintf(stderr, "Error: keywords 'java version' not found in '%s'\n", first32);
+        // // }
+        if (j != NULL && v != NULL) {
+            result = extractJavaVersion(first32, index, outVersionStr, outVersionInt);
+        }
+    }
+
+    return result;
+}
+
+// --------------
+
+// Checks whether we can find $PATH/java.exe.
+// inOutPath should be the directory where we're looking at.
+// In output, it will be the java path we tested.
+// Returns the java version integer found (e.g. 1006 for 1.6).
+// Return 0 in case of error.
+static int checkPath(CPath *inOutPath) {
+
+    // Append java.exe to path if not already present
+    CString &p = (CString&)*inOutPath;
+    int n = p.GetLength();
+    if (n < 9 || p.Right(9).CompareNoCase(_T("\\java.exe")) != 0) {
+        inOutPath->Append(_T("java.exe"));
+    }
+
+    int result = 0;
+    PVOID oldWow64Value = disableWow64FsRedirection();
+    if (inOutPath->FileExists()) {
+        // Run java -version
+        // Reject the version if it's not at least our current minimum.
+        CString versionStr;
+        if (!getJavaVersion(*inOutPath, &versionStr, &result)) {
+            result = 0;
+        }
+    }
+
+    revertWow64FsRedirection(oldWow64Value);
+    return result;
+}
+
+// Check whether we can find $PATH/bin/java.exe
+// Returns the Java version found (e.g. 1006 for 1.6) or 0 in case of error.
+static int checkBinPath(CPath *inOutPath) {
+
+    // Append bin to path if not already present
+    CString &p = (CString&)*inOutPath;
+    int n = p.GetLength();
+    if (n < 4 || p.Right(4).CompareNoCase(_T("\\bin")) != 0) {
+        inOutPath->Append(_T("bin"));
+    }
+
+    return checkPath(inOutPath);
+}
+
+// Search java.exe in the environment
+static void findJavaInEnvPath(std::set<CJavaPath> *outPaths) {
+    ::SetLastError(0);
+
+    const TCHAR* envPath = _tgetenv(_T("JAVA_HOME"));
+    if (envPath != NULL) {
+        CPath p(envPath);
+        int v = checkBinPath(&p);
+        if (v > 0) {
+            outPaths->insert(CJavaPath(v, p));
+        }
+    }
+
+    envPath = _tgetenv(_T("PATH"));
+    if (envPath != NULL) {
+        // Otherwise look at the entries in the current path.
+        // If we find more than one, keep the one with the highest version.
+        CString pathTokens(envPath);
+        int curPos = 0;
+        CString tok;
+        do {
+            tok = pathTokens.Tokenize(_T(";"), curPos);
+            if (!tok.IsEmpty()) {
+                CPath p(tok);
+                int v = checkPath(&p);
+                if (v > 0) {
+                    outPaths->insert(CJavaPath(v, p));
+                }
+            }
+        } while (!tok.IsEmpty());
+    }
+}
+
+
+// --------------
+
+static bool getRegValue(const TCHAR *keyPath,
+                        const TCHAR *keyName,
+                        REGSAM access,
+                        CString *outValue) {
+    HKEY key;
+    LSTATUS status = RegOpenKeyEx(
+        HKEY_LOCAL_MACHINE,         // hKey
+        keyPath,                    // lpSubKey
+        0,                          // ulOptions
+        KEY_READ | access,          // samDesired,
+        &key);                      // phkResult
+    if (status == ERROR_SUCCESS) {
+        LSTATUS ret = ERROR_MORE_DATA;
+        DWORD size = 4096; // MAX_PATH is 260, so 4 KB should be good enough
+        TCHAR* buffer = (TCHAR*)malloc(size);
+
+        while (ret == ERROR_MORE_DATA && size < (1 << 16) /*64 KB*/) {
+            ret = RegQueryValueEx(
+                key,                // hKey
+                keyName,            // lpValueName
+                NULL,               // lpReserved
+                NULL,               // lpType
+                (LPBYTE)buffer,     // lpData
+                &size);             // lpcbData
+
+            if (ret == ERROR_MORE_DATA) {
+                size *= 2;
+                buffer = (TCHAR*)realloc(buffer, size);
+            } else {
+                buffer[size] = 0;
+            }
+        }
+
+        if (ret != ERROR_MORE_DATA) {
+            outValue->SetString(buffer);
+        }
+
+        free(buffer);
+        RegCloseKey(key);
+
+        return (ret != ERROR_MORE_DATA);
+    }
+
+    return false;
+}
+
+// Explore the registry to find a suitable version of Java.
+// Returns an int which is the version of Java found (e.g. 1006 for 1.6) and the
+// matching path in outJavaPath.
+// Returns 0 if nothing suitable was found.
+static int exploreJavaRegistry(const TCHAR *entry, REGSAM access, std::set<CJavaPath> *outPaths) {
+
+    // Let's visit HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment [CurrentVersion]
+    CPath rootKey(_T("SOFTWARE\\JavaSoft\\"));
+    rootKey.Append(entry);
+
+    CString currentVersion;
+    CPath subKey(rootKey);
+    if (getRegValue(subKey, _T("CurrentVersion"), access, &currentVersion)) {
+        // CurrentVersion should be something like "1.7".
+        // We want to read HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\1.7 [JavaHome]
+        subKey.Append(currentVersion);
+        CString value;
+        if (getRegValue(subKey, _T("JavaHome"), access, &value)) {
+            CPath javaHome(value);
+            int v = checkBinPath(&javaHome);
+            if (v > 0) {
+                outPaths->insert(CJavaPath(v, javaHome));
+            }
+        }
+    }
+
+    // Try again, but this time look at all the versions available
+    HKEY javaHomeKey;
+    LSTATUS status = RegOpenKeyEx(
+        HKEY_LOCAL_MACHINE,         // hKey
+        _T("SOFTWARE\\JavaSoft"),   // lpSubKey
+        0,                          // ulOptions
+        KEY_READ | access,          // samDesired
+        &javaHomeKey);              // phkResult
+    if (status == ERROR_SUCCESS) {
+        TCHAR name[MAX_PATH + 1];
+        DWORD index = 0;
+        CPath javaHome;
+        for (LONG result = ERROR_SUCCESS; result == ERROR_SUCCESS; index++) {
+            DWORD nameLen = MAX_PATH;
+            name[nameLen] = 0;
+            result = RegEnumKeyEx(
+                javaHomeKey,  // hKey
+                index,        // dwIndex
+                name,         // lpName
+                &nameLen,     // lpcName
+                NULL,         // lpReserved
+                NULL,         // lpClass
+                NULL,         // lpcClass,
+                NULL);        // lpftLastWriteTime
+            if (result == ERROR_SUCCESS && nameLen < MAX_PATH) {
+                name[nameLen] = 0;
+                CPath subKey(rootKey);
+                subKey.Append(name);
+
+                CString value;
+                if (getRegValue(subKey, _T("JavaHome"), access, &value)) {
+                    CPath javaHome(value);
+                    int v = checkBinPath(&javaHome);
+                    if (v > 0) {
+                        outPaths->insert(CJavaPath(v, javaHome));
+                    }
+                }
+            }
+        }
+
+        RegCloseKey(javaHomeKey);
+    }
+
+    return 0;
+}
+
+static void findJavaInRegistry(std::set<CJavaPath> *outPaths) {
+    // We'll do the registry test 3 times: first using the default mode,
+    // then forcing the use of the 32-bit registry then forcing the use of
+    // 64-bit registry. On Windows 2k, the 2 latter will fail since the
+    // flags are not supported. On a 32-bit OS the 64-bit is obviously
+    // useless and the 2 first tests should be equivalent so we just
+    // need the first case.
+
+    // Check the JRE first, then the JDK.
+    exploreJavaRegistry(_T("Java Runtime Environment"), 0, outPaths);
+    exploreJavaRegistry(_T("Java Development Kit"), 0, outPaths);
+
+    // Get the app sysinfo state (the one hidden by WOW64)
+    SYSTEM_INFO sysInfo;
+    GetSystemInfo(&sysInfo);
+    WORD programArch = sysInfo.wProcessorArchitecture;
+    // Check the real sysinfo state (not the one hidden by WOW64) for x86
+    GetNativeSystemInfo(&sysInfo);
+    WORD actualArch = sysInfo.wProcessorArchitecture;
+
+    // Only try to access the WOW64-32 redirected keys on a 64-bit system.
+    // There's no point in doing this on a 32-bit system.
+    if (actualArch == PROCESSOR_ARCHITECTURE_AMD64) {
+        if (programArch != PROCESSOR_ARCHITECTURE_INTEL) {
+            // If we did the 32-bit case earlier, don't do it twice.
+            exploreJavaRegistry(_T("Java Runtime Environment"), KEY_WOW64_32KEY, outPaths);
+            exploreJavaRegistry(_T("Java Development Kit"),     KEY_WOW64_32KEY, outPaths);
+
+        } else if (programArch != PROCESSOR_ARCHITECTURE_AMD64) {
+            // If we did the 64-bit case earlier, don't do it twice.
+            exploreJavaRegistry(_T("Java Runtime Environment"), KEY_WOW64_64KEY, outPaths);
+            exploreJavaRegistry(_T("Java Development Kit"),     KEY_WOW64_64KEY, outPaths);
+        }
+    }
+}
+
+// --------------
+
+static void checkProgramFiles(std::set<CJavaPath> *outPaths) {
+
+    TCHAR programFilesPath[MAX_PATH + 1];
+    HRESULT result = SHGetFolderPath(
+        NULL,                       // hwndOwner
+        CSIDL_PROGRAM_FILES,        // nFolder
+        NULL,                       // hToken
+        SHGFP_TYPE_CURRENT,         // dwFlags
+        programFilesPath);          // pszPath
+
+    CPath path(programFilesPath);
+    path.Append(_T("Java"));
+
+    // Do we have a C:\\Program Files\\Java directory?
+    if (!path.IsDirectory()) {
+        return;
+    }
+
+    CPath glob(path);
+    glob.Append(_T("j*"));
+
+    WIN32_FIND_DATA findData;
+    HANDLE findH = FindFirstFile(glob, &findData);
+    if (findH == INVALID_HANDLE_VALUE) {
+        return;
+    }
+    do {
+        if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
+            CPath temp(path);
+            temp.Append(findData.cFileName);
+            // Check C:\\Program Files[x86]\\Java\\j*\\bin\\java.exe
+            int v = checkBinPath(&temp);
+            if (v > 0) {
+                outPaths->insert(CJavaPath(v, temp));
+            }
+        }
+    } while (FindNextFile(findH, &findData) != 0);
+    FindClose(findH);
+}
+
+static void findJavaInProgramFiles(std::set<CJavaPath> *outPaths) {
+    // Check the C:\\Program Files (x86) directory
+    // With WOW64 fs redirection in place by default, we should get the x86
+    // version on a 64-bit OS since this app is a 32-bit itself.
+    checkProgramFiles(outPaths);
+
+    // Check the real sysinfo state (not the one hidden by WOW64) for x86
+    SYSTEM_INFO sysInfo;
+    GetNativeSystemInfo(&sysInfo);
+
+    if (sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
+        // On a 64-bit OS, try again by disabling the fs redirection so
+        // that we can try the real C:\\Program Files directory.
+        PVOID oldWow64Value = disableWow64FsRedirection();
+        checkProgramFiles(outPaths);
+        revertWow64FsRedirection(oldWow64Value);
+    }
+}
+
+//------
+
+
+CJavaFinder::CJavaFinder(int minVersion) : mMinVersion(minVersion) {
+}
+
+
+CJavaFinder::~CJavaFinder() {
+}
+
+/*
+ * Checks whether there's a recorded path in the registry and whether
+ * this path still points to a valid Java executable.
+ * Returns false if any of these do not match,
+ * Returns true if both condition match,
+ * outPath contains the result path when returning true.
+*/
+CJavaPath CJavaFinder::getRegistryPath() {
+    CString existing;
+    CRegKey rk;
+
+    if (rk.Open(HKEY_CURRENT_USER, JF_REGISTRY_KEY, KEY_READ) == ERROR_SUCCESS) {
+        ULONG sLen = MAX_PATH;
+        TCHAR s[MAX_PATH + 1];
+        if (rk.QueryStringValue(JF_REGISTRY_VALUE_PATH, s, &sLen) == ERROR_SUCCESS) {
+            existing.SetString(s);
+        }
+        rk.Close();
+    }
+
+    if (!existing.IsEmpty()) {
+        CJavaPath javaPath;
+        if (checkJavaPath(existing, &javaPath)) {
+            return javaPath;
+        }
+    }
+
+    return CJavaPath::sEmpty;
+}
+
+bool CJavaFinder::setRegistryPath(const CJavaPath &javaPath) {
+    CRegKey rk;
+
+    if (rk.Create(HKEY_CURRENT_USER, JF_REGISTRY_KEY) == ERROR_SUCCESS) {
+        bool ok = rk.SetStringValue(JF_REGISTRY_VALUE_PATH, javaPath.mPath, REG_SZ) == ERROR_SUCCESS &&
+                  rk.SetStringValue(JF_REGISTRY_VALUE_VERS, javaPath.getVersion(), REG_SZ) == ERROR_SUCCESS;
+        rk.Close();
+        return ok;
+    }
+
+    return false;
+}
+
+void CJavaFinder::findJavaPaths(std::set<CJavaPath> *paths) {
+    findJavaInEnvPath(paths);
+    findJavaInProgramFiles(paths);
+    findJavaInRegistry(paths);
+
+    // Exclude any entries that do not match the minimum version.
+    // The set is going to be fairly small so it's easier to do it here
+    // than add the filter logic in all the static methods above.
+    if (mMinVersion > 0) {
+        for (auto it = paths->begin(); it != paths->end(); ) {
+            if (it->mVersion < mMinVersion) {
+                it = paths->erase(it);  // C++11 set.erase returns an iterator to the *next* element
+            } else {
+                ++it;
+            }
+        }
+    }
+}
+
+bool CJavaFinder::checkJavaPath(const CString &path, CJavaPath *outPath) {
+    CPath p(path);
+
+    // try this path (if it ends with java.exe) or path\\java.exe
+    int v = checkPath(&p);
+    if (v == 0) {
+        // reset path and try path\\bin\\java.exe
+        p = CPath(path);
+        v = checkBinPath(&p);
+    }
+
+    if (v > 0) {
+        outPath->set(v, p);
+        return v >= mMinVersion;
+    }
+
+    return false;
+}
+
diff --git a/find_java2/src/JavaFinder.h b/find_java2/src/JavaFinder.h
new file mode 100755
index 0000000..c22b008
--- /dev/null
+++ b/find_java2/src/JavaFinder.h
@@ -0,0 +1,52 @@
+/*
+* Copyright (C) 2014 The Android Open Source Project
+*
+* 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.
+*/
+
+#pragma once
+
+
+#include <set>                                  // STL std::set
+#include "JavaPath.h"
+
+class CJavaFinder {
+public:
+    // Creates a new JavaFinder.
+    // minVersion to accept, using JAVA_VERS_TO_INT macro. 0 to accept everything.
+    CJavaFinder(int minVersion = 0);
+    ~CJavaFinder();
+
+    int getMinVersion() const { return mMinVersion;  }
+
+    // Returns the path recorded in the registry.
+    // If there is no path or it is no longer valid, returns an empty string.
+    CJavaPath getRegistryPath();
+
+    // Sets the given path as the default to use in the registry.
+    // Returns true on success.
+    bool setRegistryPath(const CJavaPath &javaPath);
+
+    // Scans the registry, the environment and program files for potential Java.exe locations.
+    // Fills the given set with the tuples (version, path) found, guaranteed sorted and unique.
+    void findJavaPaths(std::set<CJavaPath> *paths);
+
+    // Checks the given path for a given java.exe.
+    // Input path variation tried are: path as-is, path/java.exe or path/bin/java.exe.
+    // Places the java path and version in outPath;
+    // Returns true if a java path was found *and* its version is at least mMinVersion.
+    bool checkJavaPath(const CString &path, CJavaPath *outPath);
+
+private:
+    int mMinVersion;
+};
diff --git a/find_java2/src/JavaPath.cpp b/find_java2/src/JavaPath.cpp
new file mode 100755
index 0000000..ebe30c5
--- /dev/null
+++ b/find_java2/src/JavaPath.cpp
@@ -0,0 +1,97 @@
+/*
+* Copyright (C) 2014 The Android Open Source Project
+*
+* 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"
+#include "JavaPath.h"
+#include "utils.h"
+
+#define  _CRT_SECURE_NO_WARNINGS
+
+// --------------
+
+const CJavaPath CJavaPath::sEmpty = CJavaPath();
+
+CJavaPath::CJavaPath(int version, CPath path) : mVersion(version), mPath(path) {
+    mPath.Canonicalize();
+}
+
+bool CJavaPath::isEmpty() const {
+    return mVersion <= 0;
+}
+
+void CJavaPath::clear() {
+    mVersion = 0;
+    mPath = CPath();
+}
+
+void CJavaPath::set(int version, CPath path) {
+    mVersion = version;
+    mPath = path;
+    mPath.Canonicalize();
+}
+
+CString CJavaPath::getVersion() const {
+    CString s;
+    s.Format(_T("%d.%d"), JAVA_MAJOR(mVersion), JAVA_MINOR(mVersion));
+    return s;
+}
+
+
+bool CJavaPath::toShortPath() {
+    const TCHAR *longPath = mPath;
+    if (longPath == nullptr) {
+        return false;
+    }
+
+    DWORD lenShort = _tcslen(longPath) + 1;
+    TCHAR *shortPath = (TCHAR *)malloc(lenShort * sizeof(TCHAR));
+
+    DWORD length = GetShortPathName(longPath, shortPath, lenShort);
+    if (length > lenShort) {
+        // The buffer wasn't big enough, this is the size to use.
+        free(shortPath);
+        lenShort = length;
+        shortPath = (TCHAR *)malloc(length);
+        length = GetShortPathName(longPath, shortPath, lenShort);
+    }
+
+    if (length != 0) {
+        mPath = CPath(shortPath);
+    }
+
+    free(shortPath);
+    return length != 0;
+}
+
+bool CJavaPath::operator< (const CJavaPath& rhs) const {
+    if (mVersion != rhs.mVersion) {
+        // sort in reverse order on the version
+        return rhs.mVersion > mVersion;
+    }
+    // sort in normal order on the path
+    const CString &pl = mPath;
+    const CString &pr = rhs.mPath;
+    return pl.Compare(pr) < 0;
+}
+
+bool CJavaPath::operator== (const CJavaPath& rhs) const {
+    if (mVersion == rhs.mVersion) {
+        const CString &pl = mPath;
+        const CString &pr = rhs.mPath;
+        return pl.Compare(pr) == 0;
+    }
+    return false;
+}
diff --git a/find_java2/src/JavaPath.h b/find_java2/src/JavaPath.h
new file mode 100755
index 0000000..b7f40a5
--- /dev/null
+++ b/find_java2/src/JavaPath.h
@@ -0,0 +1,57 @@
+/*
+* Copyright (C) 2014 The Android Open Source Project
+*
+* 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.
+*/
+
+#pragma once
+
+#include <atlpath.h>                            // ATL CPath
+
+
+// Transforms a Java major.minor number (e.g. "1.7") to internal int value (1007)
+#define JAVA_VERS_TO_INT(major, minor)  ((major) * 1000 + (minor))
+// Extracts the major part from the internal int major.minor number
+#define JAVA_MAJOR(majorMinor)          ((majorMinor) / 1000)
+// Extracts the minor part from the internal int major.minor number
+#define JAVA_MINOR(majorMinor)          ((majorMinor) % 1000)
+
+
+struct CJavaPath {
+    int mVersion;
+    CPath mPath;
+
+    // Static empty path that can be returned as a reference.
+    static const CJavaPath sEmpty;
+
+    CJavaPath() : mVersion(0) {}
+    CJavaPath(int version, CPath path);
+    void set(int version, CPath path);
+
+    // Returns true if path/version is empty/0
+    bool isEmpty() const;
+
+    // Clears path and version to 0
+    void clear();
+
+    // Converts the internal path into a short DOS path.
+    // Returns true if this was possible and false if the conversion failed.
+    bool toShortPath();
+
+    // Returns the version formatted as a string (e.g. "1.7" instead of 1007.)
+    CString getVersion() const;
+
+    // Operators < and == for this to be suitable in an ordered std::set
+    bool operator<  (const CJavaPath& rhs) const;
+    bool operator== (const CJavaPath& rhs) const;
+};
diff --git a/find_java2/src/WinLauncher2App.cpp b/find_java2/src/WinLauncher2App.cpp
new file mode 100755
index 0000000..392ad9e
--- /dev/null
+++ b/find_java2/src/WinLauncher2App.cpp
@@ -0,0 +1,154 @@
+/*
+* Copyright (C) 2014 The Android Open Source Project
+*
+* 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"
+#include "WinLauncher2App.h"
+
+#include "utils.h"
+#include "JavaFinder.h"
+#include "FindJava2Dlg.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CWinLauncher2App
+
+BEGIN_MESSAGE_MAP(CWinLauncher2App, CWinApp)
+    ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
+END_MESSAGE_MAP()
+
+
+// The one and only CWinLauncher2App object
+CWinLauncher2App theApp;
+
+class CLauncherCmdLineInfo : public CCommandLineInfo {
+public:
+    bool mDoHelp;
+    bool mDoForceUi;
+    bool mDoJava1_7;
+    CString mFilename;
+
+    CLauncherCmdLineInfo() : mDoHelp(false), mDoForceUi(false), mDoJava1_7(false) {}
+
+    virtual void ParseParam(const TCHAR* pszParam, BOOL bFlag, BOOL bLast) {
+        // Expected command line:
+        // /h | help  : msg box with command line arguments
+        // /f | force : force UI selection
+        // /7         : require java 1.7
+        // path-to-launch
+
+        if (!bFlag) {
+            mFilename = pszParam;
+        } else if (_tcsnccmp(pszParam, _T("h"), 2) == 0) {
+            mDoHelp = true;
+        } else if (_tcsnccmp(pszParam, _T("f"), 2) == 0) {
+            mDoForceUi = true;
+        } else if (_tcsnccmp(pszParam, _T("7"), 2) == 0) {
+            mDoJava1_7 = true;
+        }
+    }
+};
+
+
+CWinLauncher2App::CWinLauncher2App() {
+    // support Restart Manager
+    m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
+
+    // TODO: add construction code here,
+    // Place all significant initialization in InitInstance
+}
+
+BOOL CWinLauncher2App::InitInstance() {
+    // InitCommonControlsEx() is required on Windows XP if an application
+    // manifest specifies use of ComCtl32.dll version 6 or later to enable
+    // visual styles.  Otherwise, any window creation will fail.
+    INITCOMMONCONTROLSEX InitCtrls;
+    InitCtrls.dwSize = sizeof(InitCtrls);
+    // Set this to include all the common control classes you want to use
+    // in your application.
+    InitCtrls.dwICC = ICC_WIN95_CLASSES;
+    InitCommonControlsEx(&InitCtrls);
+
+    CWinApp::InitInstance();
+    AfxEnableControlContainer();
+
+    // Create the shell manager, in case the dialog contains
+    // any shell tree view or shell list view controls.
+    CShellManager *pShellManager = new CShellManager;
+
+    // Activate "Windows Native" visual manager for enabling themes in MFC controls
+    CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
+
+    // Set CWinApp default registry key. Must be consistent with all apps using findjava2.
+    SetRegistryKey(_T("Android-FindJava2"));
+
+    // Use VERSIONINFO.FileDescription as the canonical app name
+    initUtils(NULL);
+
+    CLauncherCmdLineInfo cmdLine;
+    ParseCommandLine(cmdLine);
+
+    if (cmdLine.mDoHelp) {
+        const TCHAR *msg =
+            _T("WinLauncher2 [/7|/f|/h]\r\n")
+            _T("/7 : Requires Java 1.7 instead of 1.6\r\n")
+            _T("/f : Force UI\r\n")
+            _T("/h : Help\r\n");
+            AfxMessageBox(msg);
+        return FALSE; // quit without starting MFC app msg loop
+    }
+
+    CJavaFinder javaFinder(JAVA_VERS_TO_INT(1, cmdLine.mDoJava1_7 ? 7 : 6));
+    CJavaPath javaPath = javaFinder.getRegistryPath();
+    if (cmdLine.mDoForceUi || javaPath.isEmpty()) {
+        javaPath.clear();
+
+        CFindJava2Dlg dlg;
+        dlg.setJavaFinder(&javaFinder);
+        m_pMainWnd = &dlg;
+        INT_PTR nResponse = dlg.DoModal();
+
+        if (nResponse == IDOK) {
+            // Use choice selected by user and save in registry.
+            javaPath = dlg.getSelectedPath();
+            javaFinder.setRegistryPath(javaPath);
+        } else if (nResponse == IDCANCEL) {
+            // Canceled by user, exit silently.
+        } else if (nResponse == -1) {
+            TRACE(traceAppMsg, 0, "Warning: dialog creation failed, so application is terminating unexpectedly.\n");
+        }
+    }
+
+    if (!javaPath.isEmpty()) {
+        // TODO actually launch configured app instead of just printing path.
+        CString msg(_T("PLACEHOLDER TODO run app using "));
+        msg.Append(javaPath.mPath);
+        AfxMessageBox(msg);
+    }
+
+    // Delete the shell manager created above.
+    if (pShellManager != NULL) {
+        delete pShellManager;
+    }
+
+    // Since the dialog has been closed, return FALSE so that we exit the
+    // application, rather than start the application's message pump.
+    return FALSE;
+}
+
diff --git a/find_java2/src/WinLauncher2App.h b/find_java2/src/WinLauncher2App.h
new file mode 100755
index 0000000..11aca97
--- /dev/null
+++ b/find_java2/src/WinLauncher2App.h
@@ -0,0 +1,43 @@
+/*
+* Copyright (C) 2014 The Android Open Source Project
+*
+* 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.
+*/
+
+#pragma once
+
+#ifndef __AFXWIN_H__
+	#error "include 'stdafx.h' before including this file for PCH"
+#endif
+
+#include "resource.h"		// main symbols
+
+
+// CWinLauncher2App:
+// See WinLauncher2.cpp for the implementation of this class
+//
+
+class CWinLauncher2App : public CWinApp {
+public:
+	CWinLauncher2App();
+
+// Overrides
+public:
+	virtual BOOL InitInstance();
+
+// Implementation
+
+	DECLARE_MESSAGE_MAP()
+};
+
+extern CWinLauncher2App theApp;
\ No newline at end of file
diff --git a/find_java2/src/utils.cpp b/find_java2/src/utils.cpp
new file mode 100755
index 0000000..7c8c66b
--- /dev/null
+++ b/find_java2/src/utils.cpp
@@ -0,0 +1,282 @@
+/*
+* Copyright (C) 2014 The Android Open Source Project
+*
+* 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"
+#include "utils.h"
+
+// Set to true to get some extra debug information
+bool gIsDebug = false;
+// Set to true to output errors to stderr (for a Console app)
+// or to false to output using msg box (for a Windows UI app)
+bool gIsConsole = false;
+
+// Application name used in error dialog. Defined using initUtils()
+static CString gAppName("Find Java 2");
+
+// Called by the application to initialize the app name used in error dialog boxes.
+void initUtils(const TCHAR *appName) {
+    if (appName != NULL) {
+        gAppName = CString(appName);
+        return;
+    }
+
+    // Try to get the VERSIONINFO.FileDescription and use as app name
+    // Errors are ignored, in which case the default app name is used.
+
+    // First get the module (aka app instance) filename.
+    TCHAR moduleName[MAX_PATH + 1];
+    DWORD sz = ::GetModuleFileName(NULL /*AfxGetInstanceHandle()*/, moduleName, MAX_PATH);
+    if (sz == 0) {
+        // GetModuleFileName failed. Do nothing.
+        return;
+    }
+    moduleName[sz] = '\0';  // make sure string is properly terminated.
+
+    // Get the size of the FileVersionInfo buffer
+    DWORD obsoleteHandle; // see http://blogs.msdn.com/b/oldnewthing/archive/2007/07/31/4138786.aspx
+    DWORD fviSize = ::GetFileVersionInfoSize(moduleName, &obsoleteHandle);
+    if (fviSize == 0) {
+        return; // do nothing on error
+    }
+
+    char *fviBuffer = new char[fviSize];
+    if (::GetFileVersionInfo(moduleName, 0, fviSize, fviBuffer) != 0) {
+        VOID *vBuffer;
+        UINT vLen;
+
+        struct LANGUAGE_CODEPAGE {
+            WORD mLanguage;
+            WORD mCodePage;
+        } *lgcpBuffer;
+
+        UINT lgcpSize;
+
+        // Read the list of languages and code pages (c.f. MSDN for VerQueryValue)
+        if (::VerQueryValue(fviBuffer, _T("\\VarFileInfo\\Translation"), (LPVOID*)&lgcpBuffer, &lgcpSize) != 0 &&
+                lgcpSize >= sizeof(LANGUAGE_CODEPAGE)) {
+            // Use the first available language and code page
+            CString subBlock;
+            subBlock.Format(_T("\\StringFileInfo\\%04x%04x\\FileDescription"),
+                            lgcpBuffer[0].mLanguage,
+                            lgcpBuffer[0].mCodePage);
+            if (::VerQueryValue(fviBuffer, subBlock, &vBuffer, &vLen) != 0) {
+                gAppName.SetString((LPCTSTR)vBuffer, vLen);
+            }
+        }
+    }
+    delete[] fviBuffer;
+}
+
+CString getAppName() {
+    return gAppName;
+}
+
+
+// Displays a message in an ok+info dialog box.
+void msgBox(const TCHAR* text, ...) {
+    CString formatted;
+    va_list ap;
+    va_start(ap, text);
+    formatted.FormatV(text, ap);
+    va_end(ap);
+
+    // TODO global CString to get app name
+    MessageBox(NULL, formatted, gAppName, MB_OK | MB_ICONINFORMATION);
+}
+
+// Sets the string to the message matching Win32 GetLastError.
+// If message is non-null, it is prepended to the last error string.
+CString getLastWin32Error(const TCHAR* message) {
+    DWORD err = GetLastError();
+    CString result;
+    LPTSTR errStr;
+    if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | /* dwFlags */
+                      FORMAT_MESSAGE_FROM_SYSTEM,
+                      NULL,                             /* lpSource */
+                      err,                              /* dwMessageId */
+                      0,                                /* dwLanguageId */
+                      (LPTSTR) &errStr,                 /* out lpBuffer */
+                      0,                                /* nSize */
+                      NULL) != 0) {                     /* va_list args */
+        if (message == NULL) {
+            result.Format(_T("[%d] %s"), err, errStr);
+        } else {
+            result.Format(_T("%s[%d] %s"), message, err, errStr);
+        }
+        LocalFree(errStr);
+    }
+    return result;
+}
+
+// Displays GetLastError prefixed with a description in an error dialog box
+void displayLastError(const TCHAR *description, ...) {
+    CString formatted;
+    va_list ap;
+    va_start(ap, description);
+    formatted.FormatV(description, ap);
+    va_end(ap);
+
+    CString error = getLastWin32Error(NULL);
+    formatted.Append(_T("\r\n"));
+    formatted.Append(error);
+
+    if (gIsConsole) {
+        _ftprintf(stderr, _T("%s\n"), (LPCTSTR) formatted);
+    } else {
+        CString name(gAppName);
+        name.Append(_T(" - Error"));
+        MessageBox(NULL, formatted, name, MB_OK | MB_ICONERROR);
+    }
+}
+
+// Executes the command line. Does not wait for the program to finish.
+// The return code is from CreateProcess (0 means failure), not the running app.
+int execNoWait(const TCHAR *app, const TCHAR *params, const TCHAR *workDir) {
+    STARTUPINFO           startup;
+    PROCESS_INFORMATION   pinfo;
+
+    ZeroMemory(&pinfo, sizeof(pinfo));
+
+    ZeroMemory(&startup, sizeof(startup));
+    startup.cb = sizeof(startup);
+    startup.dwFlags = STARTF_USESHOWWINDOW;
+    startup.wShowWindow = SW_SHOWDEFAULT;
+
+    int ret = CreateProcess(
+        app,                                        /* program path */
+        (TCHAR *)params,                            /* command-line */
+        NULL,                  /* process handle is not inheritable */
+        NULL,                   /* thread handle is not inheritable */
+        TRUE,                          /* yes, inherit some handles */
+        0,                                          /* create flags */
+        NULL,                     /* use parent's environment block */
+        workDir,                 /* use parent's starting directory */
+        &startup,                 /* startup info, i.e. std handles */
+        &pinfo);
+
+    if (ret) {
+        CloseHandle(pinfo.hProcess);
+        CloseHandle(pinfo.hThread);
+    }
+
+    return ret;
+}
+
+// Executes command, waits for completion and returns exit code.
+// As indicated in MSDN for CreateProcess, callers should double-quote the program name
+// e.g. cmd="\"c:\program files\myapp.exe\" arg1 arg2";
+int execWait(const TCHAR *cmd) {
+    STARTUPINFO           startup;
+    PROCESS_INFORMATION   pinfo;
+
+    ZeroMemory(&pinfo, sizeof(pinfo));
+
+    ZeroMemory(&startup, sizeof(startup));
+    startup.cb = sizeof(startup);
+    startup.dwFlags = STARTF_USESHOWWINDOW;
+    startup.wShowWindow = SW_HIDE | SW_MINIMIZE;
+
+    int ret = CreateProcess(
+        NULL,                                       /* program path */
+        (LPTSTR)cmd,                                /* command-line */
+        NULL,                  /* process handle is not inheritable */
+        NULL,                   /* thread handle is not inheritable */
+        TRUE,                          /* yes, inherit some handles */
+        CREATE_NO_WINDOW,                /* we don't want a console */
+        NULL,                     /* use parent's environment block */
+        NULL,                    /* use parent's starting directory */
+        &startup,                 /* startup info, i.e. std handles */
+        &pinfo);
+
+    int result = -1;
+    if (ret) {
+        WaitForSingleObject(pinfo.hProcess, INFINITE);
+
+        DWORD exitCode;
+        if (GetExitCodeProcess(pinfo.hProcess, &exitCode)) {
+            // this should not return STILL_ACTIVE (259)
+            result = exitCode;
+        }
+        CloseHandle(pinfo.hProcess);
+        CloseHandle(pinfo.hThread);
+    }
+
+    return result;
+}
+
+bool getModuleDir(CPath *outDir) {
+    TCHAR programDir[MAX_PATH];
+    int ret = GetModuleFileName(NULL, programDir, sizeof(programDir) / sizeof(programDir[0]));
+    if (ret != 0) {
+        CPath dir(programDir);
+        dir.RemoveFileSpec();
+        *outDir = dir;
+        return true;
+    }
+    return false;
+}
+
+// Disables the FS redirection done by WOW64.
+// Because this runs as a 32-bit app, Windows automagically remaps some
+// folder under the hood (e.g. "Programs Files(x86)" is mapped as "Program Files").
+// This prevents the app from correctly searching for java.exe in these folders.
+// The registry is also remapped. This method disables this redirection.
+// Caller should restore the redirection later by using revertWow64FsRedirection().
+PVOID disableWow64FsRedirection() {
+
+    // The call we want to make is the following:
+    //    PVOID oldWow64Value;
+    //    Wow64DisableWow64FsRedirection(&oldWow64Value);
+    // However that method may not exist (e.g. on XP non-64 systems) so
+    // we must not call it directly.
+
+    PVOID oldWow64Value = 0;
+
+    HMODULE hmod = LoadLibrary(_T("kernel32.dll"));
+    if (hmod != NULL) {
+        FARPROC proc = GetProcAddress(hmod, "Wow64DisableWow64FsRedirection");
+        if (proc != NULL) {
+            typedef BOOL(WINAPI *disableWow64FuncType)(PVOID *);
+            disableWow64FuncType funcPtr = (disableWow64FuncType)proc;
+            funcPtr(&oldWow64Value);
+        }
+
+        FreeLibrary(hmod);
+    }
+
+    return oldWow64Value;
+}
+
+// Reverts the redirection disabled in disableWow64FsRedirection.
+void revertWow64FsRedirection(PVOID oldWow64Value) {
+
+    // The call we want to make is the following:
+    //    Wow64RevertWow64FsRedirection(oldWow64Value);
+    // However that method may not exist (e.g. on XP non-64 systems) so
+    // we must not call it directly.
+
+    HMODULE hmod = LoadLibrary(_T("kernel32.dll"));
+    if (hmod != NULL) {
+        FARPROC proc = GetProcAddress(hmod, "Wow64RevertWow64FsRedirection");
+        if (proc != NULL) {
+            typedef BOOL(WINAPI *revertWow64FuncType)(PVOID);
+            revertWow64FuncType funcPtr = (revertWow64FuncType)proc;
+            funcPtr(oldWow64Value);
+        }
+
+        FreeLibrary(hmod);
+    }
+}
diff --git a/find_java2/src/utils.h b/find_java2/src/utils.h
new file mode 100755
index 0000000..3557f58
--- /dev/null
+++ b/find_java2/src/utils.h
@@ -0,0 +1,59 @@
+/*
+* Copyright (C) 2014 The Android Open Source Project
+*
+* 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.
+*/
+
+#pragma once
+
+#include <atlpath.h>                            // ATL CPath
+
+// Global flag indicating whether this is running in debug mode (more printfs)
+extern bool gIsDebug;
+// Global flag indicating whether this is running in console mode or GUI.
+// In console mode, errors are written on the console; in GUI they use a MsgBox.
+extern bool gIsConsole;
+
+// Must be called by the application to initialize the app name used in error dialog boxes.
+// If NULL is used, fetches VERSIONINFO.FileDescription from resources if available.
+void initUtils(const TCHAR *appName);
+
+// Returns the app name set in initUtils
+CString getAppName();
+
+// Displays a message in an ok+info dialog box. Useful in console mode.
+void msgBox(const TCHAR* text, ...);
+
+// Displays GetLastError prefixed with a description in an error dialog box. Useful in console mode.
+void displayLastError(const TCHAR *description, ...);
+
+// Executes the command line. Does not wait for the program to finish.
+// The return code is from CreateProcess (0 means failure), not the running app.
+int execNoWait(const TCHAR *app, const TCHAR *params, const TCHAR *workDir);
+
+// Executes command, waits for completion and returns exit code.
+// As indicated in MSDN for CreateProcess, callers should double-quote the program name
+// e.g. cmd="\"c:\program files\myapp.exe\" arg1 arg2";
+int execWait(const TCHAR *cmd);
+
+bool getModuleDir(CPath *outDir);
+
+// Disables the FS redirection done by WOW64.
+// Because this runs as a 32-bit app, Windows automagically remaps some
+// folder under the hood (e.g. "Programs Files(x86)" is mapped as "Program Files").
+// This prevents the app from correctly searching for java.exe in these folders.
+// The registry is also remapped.
+PVOID disableWow64FsRedirection();
+
+// Reverts the redirection disabled in disableWow64FsRedirection.
+void revertWow64FsRedirection(PVOID oldWow64Value);
