from email.parser import Parser

from pkginfo._compat import StringIO
from pkginfo._compat import must_decode

def parse(fp):
    return Parser().parse(fp)
def get(msg, header):
    return _collapse_leading_ws(header, msg.get(header))
def get_all(msg, header):
    return [_collapse_leading_ws(header, x) for x in msg.get_all(header)]

def _collapse_leading_ws(header, txt):
    """
    ``Description`` header must preserve newlines; all others need not
    """
    if header.lower() == 'description':  # preserve newlines
        return '\n'.join([x[8:] if x.startswith(' ' * 8) else x
                          for x in txt.strip().splitlines()])
    else:
        return ' '.join([x.strip() for x in txt.splitlines()])

HEADER_ATTRS_1_0 = ( # PEP 241
    ('Metadata-Version', 'metadata_version', False),
    ('Name', 'name', False),
    ('Version', 'version', False),
    ('Platform', 'platforms', True),
    ('Supported-Platform', 'supported_platforms', True),
    ('Summary', 'summary', False),
    ('Description', 'description', False),
    ('Keywords', 'keywords', False),
    ('Home-Page', 'home_page', False),
    ('Author', 'author', False),
    ('Author-email', 'author_email', False),
    ('License', 'license', False),
)

HEADER_ATTRS_1_1 = HEADER_ATTRS_1_0 + ( # PEP 314
    ('Classifier', 'classifiers', True),
    ('Download-URL', 'download_url', False),
    ('Requires', 'requires', True),
    ('Provides', 'provides', True),
    ('Obsoletes', 'obsoletes', True),
)

HEADER_ATTRS_1_2 = HEADER_ATTRS_1_1 + ( # PEP 345
    ('Maintainer', 'maintainer', False),
    ('Maintainer-email', 'maintainer_email', False),
    ('Requires-Python', 'requires_python', False),
    ('Requires-External', 'requires_external', True),
    ('Requires-Dist', 'requires_dist', True),
    ('Provides-Dist', 'provides_dist', True),
    ('Obsoletes-Dist', 'obsoletes_dist', True),
    ('Project-URL', 'project_urls', True),
)

HEADER_ATTRS_2_0 = HEADER_ATTRS_1_2  #XXX PEP 426?

HEADER_ATTRS = {
    '1.0': HEADER_ATTRS_1_0,
    '1.1': HEADER_ATTRS_1_1,
    '1.2': HEADER_ATTRS_1_2,
    '2.0': HEADER_ATTRS_2_0,
}

class Distribution(object):
    metadata_version = None
    # version 1.0
    name = None
    version = None
    platforms = ()
    supported_platforms = ()
    summary = None
    description = None
    keywords = None
    home_page = None
    download_url = None
    author = None
    author_email = None
    license = None
    # version 1.1
    classifiers = ()
    requires = ()
    provides = ()
    obsoletes = ()
    # version 1.2
    maintainer = None
    maintainer_email = None
    requires_python = None
    requires_external = ()
    requires_dist = ()
    provides_dist = ()
    obsoletes_dist = ()
    project_urls = ()

    def extractMetadata(self):
        data = self.read()
        self.parse(data)

    def read(self):
        raise NotImplementedError

    def _getHeaderAttrs(self):
        return HEADER_ATTRS.get(self.metadata_version, [])

    def parse(self, data):
        fp = StringIO(must_decode(data))
        msg = parse(fp)

        if 'Metadata-Version' in msg and self.metadata_version is None:
            value = get(msg, 'Metadata-Version')
            metadata_version = self.metadata_version = value

        for header_name, attr_name, multiple in self._getHeaderAttrs():

            if attr_name == 'metadata_version':
                continue

            if header_name in msg:
                if multiple:
                    values = get_all(msg, header_name)
                    setattr(self, attr_name, values)
                else:
                    value = get(msg, header_name)
                    if value != 'UNKNOWN':
                        setattr(self, attr_name, value)

    def __iter__(self):
        for header_name, attr_name, multiple in self._getHeaderAttrs():
            yield attr_name

    iterkeys = __iter__


from __future__ import absolute_import

import logging
import tempfile
import os.path

from pip._vendor.six.moves.urllib import parse as urllib_parse
from pip._vendor.six.moves.urllib import request as urllib_request

from pip.utils import call_subprocess
from pip.utils import display_path, rmtree
from pip.vcs import vcs, VersionControl

urlsplit = urllib_parse.urlsplit
urlunsplit = urllib_parse.urlunsplit

logger = logging.getLogger(__name__)

class Git(VersionControl):
    name = 'git'
    dirname = '.git'
    repo_name = 'clone'
    schemes = (
        'git', 'git+http', 'git+https', 'git+ssh', 'git+git', 'git+file',
    )

    def __init__(self, url=None, *args, **kwargs):

        # Works around an apparent Git bug
        # (see http://article.gmane.org/gmane.comp.version-control.git/146500)
        if url:
            scheme, netloc, path, query, fragment = urlsplit(url)
            if scheme.endswith('file'):
                initial_slashes = path[:-len(path.lstrip('/'))]
                newpath = (
                    initial_slashes +
                    urllib_request.url2pathname(path)
                    .replace('\\', '/').lstrip('/')
                )
                url = urlunsplit((scheme, netloc, newpath, query, fragment))
                after_plus = scheme.find('+') + 1
                url = scheme[:after_plus] + urlunsplit(
                    (scheme[after_plus:], netloc, newpath, query, fragment),
                )

        super(Git, self).__init__(url, *args, **kwargs)

    def export(self, location):
        """Export the Git repository at the url to the destination location"""
        temp_dir = tempfile.mkdtemp('-export', 'pip-')
        self.unpack(temp_dir)
        try:
            if not location.endswith('/'):
                location = location + '/'
            call_subprocess(
                [self.cmd, 'checkout-index', '-a', '-f', '--prefix', location],
                filter_stdout=self._filter, show_stdout=False, cwd=temp_dir)
        finally:
            rmtree(temp_dir)

    def check_rev_options(self, rev, dest, rev_options):
        """Check the revision options before checkout to compensate that tags
        and branches may need origin/ as a prefix.
        Returns the SHA1 of the branch or tag if found.
        """
        revisions = self.get_refs(dest)

        origin_rev = 'origin/%s' % rev
        if origin_rev in revisions:
            # remote branch
            return [revisions[origin_rev]]
        elif rev in revisions:
            # a local tag or branch name
            return [revisions[rev]]
        else:
            logger.warning(
                "Could not find a tag or branch '%s', assuming commit.", rev,
            )
            return rev_options

    def switch(self, dest, url, rev_options):
        call_subprocess(
            [self.cmd, 'config', 'remote.origin.url', url], cwd=dest)
        call_subprocess(
            [self.cmd, 'checkout', '-q'] + rev_options, cwd=dest)

        self.update_submodules(dest)

    def update(self, dest, rev_options):
        # First fetch changes from the default remote
        call_subprocess([self.cmd, 'fetch', '-q'], cwd=dest)
        # Then reset to wanted revision (maby even origin/master)
        if rev_options:
            rev_options = self.check_rev_options(
                rev_options[0], dest, rev_options,
            )
        call_subprocess(
            [self.cmd, 'reset', '--hard', '-q'] + rev_options,
            cwd=dest,
        )
        #: update submodules
        self.update_submodules(dest)

    def obtain(self, dest):
        url, rev = self.get_url_rev()
        if rev:
            rev_options = [rev]
            rev_display = ' (to %s)' % rev
        else:
            rev_options = ['origin/master']
            rev_display = ''
        if self.check_destination(dest, url, rev_options, rev_display):
            logger.info(
                'Cloning %s%s to %s', url, rev_display, display_path(dest),
            )
            call_subprocess([self.cmd, 'clone', '-q', url, dest])

            if rev:
                rev_options = self.check_rev_options(rev, dest, rev_options)
                # Only do a checkout if rev_options differs from HEAD
                if not self.get_revision(dest).startswith(rev_options[0]):
                    call_subprocess(
                        [self.cmd, 'checkout', '-q'] + rev_options,
                        cwd=dest,
                    )
            #: repo may contain submodules
            self.update_submodules(dest)

    def get_url(self, location):
        url = call_subprocess(
            [self.cmd, 'config', 'remote.origin.url'],
            show_stdout=False, cwd=location)
        return url.strip()

    def get_revision(self, location):
        current_rev = call_subprocess(
            [self.cmd, 'rev-parse', 'HEAD'], show_stdout=False, cwd=location)
        return current_rev.strip()

    def get_refs(self, location):
        """Return map of named refs (branches or tags) to commit hashes."""
        output = call_subprocess([self.cmd, 'show-ref'],
                                 show_stdout=False, cwd=location)
        rv = {}
        for line in output.strip().splitlines():
            commit, ref = line.split(' ', 1)
            ref = ref.strip()
            ref_name = None
            if ref.startswith('refs/remotes/'):
                ref_name = ref[len('refs/remotes/'):]
            elif ref.startswith('refs/heads/'):
                ref_name = ref[len('refs/heads/'):]
            elif ref.startswith('refs/tags/'):
                ref_name = ref[len('refs/tags/'):]
            if ref_name is not None:
                rv[ref_name] = commit.strip()
        return rv

    def get_src_requirement(self, dist, location, find_tags):
        repo = self.get_url(location)
        if not repo.lower().startswith('git:'):
            repo = 'git+' + repo
        egg_project_name = dist.egg_name().split('-', 1)[0]
        if not repo:
            return None
        current_rev = self.get_revision(location)
        refs = self.get_refs(location)
        # refs maps names to commit hashes; we need the inverse
        # if multiple names map to a single commit, we pick the first one
        # alphabetically
        names_by_commit = {}
        for ref, commit in sorted(refs.items()):
            if commit not in names_by_commit:
                names_by_commit[commit] = ref

        if current_rev in names_by_commit:
            # It's a tag or branch.
            name = names_by_commit[current_rev]
            full_egg_name = (
                '%s-%s' % (egg_project_name, self.translate_egg_surname(name))
            )
        else:
            full_egg_name = '%s-dev' % egg_project_name

        return '%s@%s#egg=%s' % (repo, current_rev, full_egg_name)

    def get_url_rev(self):
        """
        Prefixes stub URLs like 'user@hostname:user/repo.git' with 'ssh://'.
        That's required because although they use SSH they sometimes doesn't
        work with a ssh:// scheme (e.g. Github). But we need a scheme for
        parsing. Hence we remove it again afterwards and return it as a stub.
        """
        if '://' not in self.url:
            assert 'file:' not in self.url
            self.url = self.url.replace('git+', 'git+ssh://')
            url, rev = super(Git, self).get_url_rev()
            url = url.replace('ssh://', '')
        else:
            url, rev = super(Git, self).get_url_rev()

        return url, rev

    def update_submodules(self, location):
        if not os.path.exists(os.path.join(location, '.gitmodules')):
            return
        call_subprocess(
            [self.cmd, 'submodule', 'update', '--init', '--recursive', '-q'],
            cwd=location,
        )

vcs.register(Git)


# System library imports
from IPython.external.qt import QtCore, QtGui

class CompletionWidget(QtGui.QListWidget):
    """ A widget for GUI tab completion.
    """

    #--------------------------------------------------------------------------
    # 'QObject' interface
    #--------------------------------------------------------------------------

    def __init__(self, console_widget):
        """ Create a completion widget that is attached to the specified Qt
            text edit widget.
        """
        text_edit = console_widget._control
        assert isinstance(text_edit, (QtGui.QTextEdit, QtGui.QPlainTextEdit))
        super(CompletionWidget, self).__init__()

        self._text_edit = text_edit

        self.setAttribute(QtCore.Qt.WA_StaticContents)
        self.setWindowFlags(QtCore.Qt.ToolTip | QtCore.Qt.WindowStaysOnTopHint)

        # Ensure that the text edit keeps focus when widget is displayed.
        self.setFocusProxy(self._text_edit)

        self.setFrameShadow(QtGui.QFrame.Plain)
        self.setFrameShape(QtGui.QFrame.StyledPanel)

        self.itemActivated.connect(self._complete_current)

    def eventFilter(self, obj, event):
        """ Reimplemented to handle keyboard input and to auto-hide when the
            text edit loses focus.
        """
        if obj == self._text_edit:
            etype = event.type()

            if etype == QtCore.QEvent.KeyPress:
                key, text = event.key(), event.text()
                if key in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter,
                           QtCore.Qt.Key_Tab):
                    self._complete_current()
                    return True
                elif key == QtCore.Qt.Key_Escape:
                    self.hide()
                    return True
                elif key in (QtCore.Qt.Key_Up, QtCore.Qt.Key_Down,
                             QtCore.Qt.Key_PageUp, QtCore.Qt.Key_PageDown,
                             QtCore.Qt.Key_Home, QtCore.Qt.Key_End):
                    self.keyPressEvent(event)
                    return True

            elif etype == QtCore.QEvent.FocusOut:
                self.hide()

        return super(CompletionWidget, self).eventFilter(obj, event)

    #--------------------------------------------------------------------------
    # 'QWidget' interface
    #--------------------------------------------------------------------------

    def hideEvent(self, event):
        """ Reimplemented to disconnect signal handlers and event filter.
        """
        super(CompletionWidget, self).hideEvent(event)
        self._text_edit.cursorPositionChanged.disconnect(self._update_current)
        self._text_edit.removeEventFilter(self)

    def showEvent(self, event):
        """ Reimplemented to connect signal handlers and event filter.
        """
        super(CompletionWidget, self).showEvent(event)
        self._text_edit.cursorPositionChanged.connect(self._update_current)
        self._text_edit.installEventFilter(self)

    #--------------------------------------------------------------------------
    # 'CompletionWidget' interface
    #--------------------------------------------------------------------------

    def show_items(self, cursor, items):
        """ Shows the completion widget with 'items' at the position specified
            by 'cursor'.
        """
        text_edit = self._text_edit
        point = text_edit.cursorRect(cursor).bottomRight()
        point = text_edit.mapToGlobal(point)
        height = self.sizeHint().height()
        screen_rect = QtGui.QApplication.desktop().availableGeometry(self)
        if screen_rect.size().height() - point.y() - height < 0:
            point = text_edit.mapToGlobal(text_edit.cursorRect().topRight())
            point.setY(point.y() - height)
        self.move(point)

        self._start_position = cursor.position()
        self.clear()
        self.addItems(items)
        self.setCurrentRow(0)
        self.show()

    #--------------------------------------------------------------------------
    # Protected interface
    #--------------------------------------------------------------------------

    def _complete_current(self):
        """ Perform the completion with the currently selected item.
        """
        self._current_text_cursor().insertText(self.currentItem().text())
        self.hide()

    def _current_text_cursor(self):
        """ Returns a cursor with text between the start position and the
            current position selected.
        """
        cursor = self._text_edit.textCursor()
        if cursor.position() >= self._start_position:
            cursor.setPosition(self._start_position,
                               QtGui.QTextCursor.KeepAnchor)
        return cursor

    def _update_current(self):
        """ Updates the current item based on the current text.
        """
        prefix = self._current_text_cursor().selection().toPlainText()
        if prefix:
            items = self.findItems(prefix, (QtCore.Qt.MatchStartsWith |
                                            QtCore.Qt.MatchCaseSensitive))
            if items:
                self.setCurrentItem(items[0])
            else:
                self.hide()
        else:
            self.hide()

    def cancel_completion(self):
        self.hide()


from django.apps import apps
from django.contrib import admin

def registerAdminSite(appName, excludeModels=[]):
    """Registers the models of the app with the given "appName" for the admin site"""
    for model in apps.get_app_config(appName).get_models():
        if model not in excludeModels:
            admin.site.register(model)


#!/usr/bin/env python
#
# $Id: _psmswindows.py 1514 2012-08-14 11:16:56Z g.rodola $
#
# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Windows platform implementation."""

import errno
import os
import sys
import platform

import _psutil_mswindows
from _psutil_mswindows import ERROR_ACCESS_DENIED
from psutil.error import AccessDenied, NoSuchProcess, TimeoutExpired
from psutil._common import *
from psutil._compat import PY3, xrange, long

# Windows specific extended namespace
__extra__all__ = ["ABOVE_NORMAL_PRIORITY_CLASS", "BELOW_NORMAL_PRIORITY_CLASS",
                  "HIGH_PRIORITY_CLASS", "IDLE_PRIORITY_CLASS",
                  "NORMAL_PRIORITY_CLASS", "REALTIME_PRIORITY_CLASS"]

# --- module level constants (gets pushed up to psutil module)

NUM_CPUS = _psutil_mswindows.get_num_cpus()
BOOT_TIME = _psutil_mswindows.get_system_uptime()
TOTAL_PHYMEM = _psutil_mswindows.get_virtual_mem()[0]
WAIT_TIMEOUT = 0x00000102 # 258 in decimal
ACCESS_DENIED_SET = frozenset([errno.EPERM, errno.EACCES, ERROR_ACCESS_DENIED])

# process priority constants:
# http://msdn.microsoft.com/en-us/library/ms686219(v=vs.85).aspx
from _psutil_mswindows import (ABOVE_NORMAL_PRIORITY_CLASS,
                               BELOW_NORMAL_PRIORITY_CLASS,
                               HIGH_PRIORITY_CLASS,
                               IDLE_PRIORITY_CLASS,
                               NORMAL_PRIORITY_CLASS,
                               REALTIME_PRIORITY_CLASS,
                               INFINITE)

@memoize
def _win32_QueryDosDevice(s):
    return _psutil_mswindows.win32_QueryDosDevice(s)

def _convert_raw_path(s):
    # convert paths using native DOS format like:
    # "\Device\HarddiskVolume1\Windows\systemew\file.txt"
    # into: "C:\Windows\systemew\file.txt"
    if PY3 and not isinstance(s, str):
        s = s.decode('utf8')
    rawdrive = '\\'.join(s.split('\\')[:3])
    driveletter = _win32_QueryDosDevice(rawdrive)
    return os.path.join(driveletter, s[len(rawdrive):])

# --- public functions

nt_virtmem_info = namedtuple('vmem', ' '.join([
    # all platforms
    'total', 'available', 'percent', 'used', 'free']))

def virtual_memory():
    """System virtual memory as a namedtuple."""
    mem = _psutil_mswindows.get_virtual_mem()
    totphys, availphys, totpagef, availpagef, totvirt, freevirt = mem
    #
    total = totphys
    avail = availphys
    free = availphys
    used = total - avail
    percent = usage_percent((total - avail), total, _round=1)
    return nt_virtmem_info(total, avail, percent, used, free)

def swap_memory():
    """Swap system memory as a (total, used, free, sin, sout) tuple."""
    mem = _psutil_mswindows.get_virtual_mem()
    total = mem[2]
    free = mem[3]
    used = total - free
    percent = usage_percent(used, total, _round=1)
    return nt_swapmeminfo(total, used, free, percent, 0, 0)

def get_disk_usage(path):
    """Return disk usage associated with path."""
    try:
        total, free = _psutil_mswindows.get_disk_usage(path)
    except WindowsError:
        err = sys.exc_info()[1]
        if not os.path.exists(path):
            raise OSError(errno.ENOENT, "No such file or directory: '%s'" % path)
        raise
    used = total - free
    percent = usage_percent(used, total, _round=1)
    return nt_diskinfo(total, used, free, percent)

def disk_partitions(all):
    """Return disk partitions."""
    rawlist = _psutil_mswindows.get_disk_partitions(all)
    return [nt_partition(*x) for x in rawlist]

_cputimes_ntuple = namedtuple('cputimes', 'user system idle')

def get_system_cpu_times():
    """Return system CPU times as a named tuple."""
    user, system, idle = 0, 0, 0
    # computes system global times summing each processor value
    for cpu_time in _psutil_mswindows.get_system_cpu_times():
        user += cpu_time[0]
        system += cpu_time[1]
        idle += cpu_time[2]
    return _cputimes_ntuple(user, system, idle)

def get_system_per_cpu_times():
    """Return system per-CPU times as a list of named tuples."""
    ret = []
    for cpu_t in _psutil_mswindows.get_system_cpu_times():
        user, system, idle = cpu_t
        item = _cputimes_ntuple(user, system, idle)
        ret.append(item)
    return ret

def get_system_users():
    """Return currently connected users as a list of namedtuples."""
    retlist = []
    rawlist = _psutil_mswindows.get_system_users()
    for item in rawlist:
        user, hostname, tstamp = item
        nt = nt_user(user, None, hostname, tstamp)
        retlist.append(nt)
    return retlist

get_pid_list = _psutil_mswindows.get_pid_list
pid_exists = _psutil_mswindows.pid_exists
network_io_counters = _psutil_mswindows.get_network_io_counters
disk_io_counters = _psutil_mswindows.get_disk_io_counters

# --- decorator

def wrap_exceptions(callable):
    """Call callable into a try/except clause so that if a
    WindowsError 5 AccessDenied exception is raised we translate it
    into psutil.AccessDenied
    """
    def wrapper(self, *args, **kwargs):
        try:
            return callable(self, *args, **kwargs)
        except OSError:
            err = sys.exc_info()[1]
            if err.errno in ACCESS_DENIED_SET:
                raise AccessDenied(self.pid, self._process_name)
            if err.errno == errno.ESRCH:
                raise NoSuchProcess(self.pid, self._process_name)
            raise
    return wrapper

class Process(object):
    """Wrapper class around underlying C implementation."""

    __slots__ = ["pid", "_process_name"]

    def __init__(self, pid):
        self.pid = pid
        self._process_name = None

    @wrap_exceptions
    def get_process_name(self):
        """Return process name as a string of limited len (15)."""
        return _psutil_mswindows.get_process_name(self.pid)

    @wrap_exceptions
    def get_process_exe(self):
        # Note: os.path.exists(path) may return False even if the file
        # is there, see:
        # http://stackoverflow.com/questions/3112546/os-path-exists-lies
        return _convert_raw_path(_psutil_mswindows.get_process_exe(self.pid))

    @wrap_exceptions
    def get_process_cmdline(self):
        """Return process cmdline as a list of arguments."""
        return _psutil_mswindows.get_process_cmdline(self.pid)

    @wrap_exceptions
    def get_process_ppid(self):
        """Return process parent pid."""
        return _psutil_mswindows.get_process_ppid(self.pid)

    def _get_raw_meminfo(self):
        try:
            return _psutil_mswindows.get_process_memory_info(self.pid)
        except OSError:
            err = sys.exc_info()[1]
            if err.errno in ACCESS_DENIED_SET:
                return _psutil_mswindows.get_process_memory_info_2(self.pid)
            raise

    @wrap_exceptions
    def get_memory_info(self):
        """Returns a tuple or RSS/VMS memory usage in bytes."""
        # on Windows RSS == WorkingSetSize and VSM == PagefileUsage
        # fields of PROCESS_MEMORY_COUNTERS struct:
        # http://msdn.microsoft.com/en-us/library/windows/desktop/ms684877(v=vs.85).aspx
        t = self._get_raw_meminfo()
        return nt_meminfo(t[2], t[7])

    _nt_ext_mem = namedtuple('meminfo',
        ' '.join(['num_page_faults',
                  'peak_wset',
                  'wset',
                  'peak_paged_pool',
                  'paged_pool',
                  'peak_nonpaged_pool',
                  'nonpaged_pool',
                  'pagefile',
                  'peak_pagefile',
                  'private',]))

    @wrap_exceptions
    def get_ext_memory_info(self):
        return self._nt_ext_mem(*self._get_raw_meminfo())

    nt_mmap_grouped = namedtuple('mmap', 'path rss')
    nt_mmap_ext = namedtuple('mmap', 'addr perms path rss')

    def get_memory_maps(self):
        try:
            raw = _psutil_mswindows.get_process_memory_maps(self.pid)
        except OSError:
            # XXX - can't use wrap_exceptions decorator as we're
            # returning a generator; probably needs refactoring.
            err = sys.exc_info()[1]
            if err.errno in (errno.EPERM, errno.EACCES, ERROR_ACCESS_DENIED):
                raise AccessDenied(self.pid, self._process_name)
            if err.errno == errno.ESRCH:
                raise NoSuchProcess(self.pid, self._process_name)
            raise
        else:
            for addr, perm, path, rss in raw:
                path = _convert_raw_path(path)
                addr = hex(addr)
                yield (addr, perm, path, rss)

    @wrap_exceptions
    def kill_process(self):
        """Terminates the process with the given PID."""
        return _psutil_mswindows.kill_process(self.pid)

    @wrap_exceptions
    def process_wait(self, timeout=None):
        if timeout is None:
            timeout = INFINITE
        else:
            # WaitForSingleObject() expects time in milliseconds
            timeout = int(timeout * 1000)
        ret = _psutil_mswindows.process_wait(self.pid, timeout)
        if ret == WAIT_TIMEOUT:
            raise TimeoutExpired(self.pid, self._process_name)
        return ret

    @wrap_exceptions
    def get_process_username(self):
        """Return the name of the user that owns the process"""
        if self.pid in (0, 4):
            return 'NT AUTHORITY\\SYSTEM'
        return _psutil_mswindows.get_process_username(self.pid)

    @wrap_exceptions
    def get_process_create_time(self):
        # special case for kernel process PIDs; return system boot time
        if self.pid in (0, 4):
            return BOOT_TIME
        try:
            return _psutil_mswindows.get_process_create_time(self.pid)
        except OSError:
            err = sys.exc_info()[1]
            if err.errno in ACCESS_DENIED_SET:
                return _psutil_mswindows.get_process_create_time_2(self.pid)
            raise

    @wrap_exceptions
    def get_process_num_threads(self):
        return _psutil_mswindows.get_process_num_threads(self.pid)

    @wrap_exceptions
    def get_process_threads(self):
        rawlist = _psutil_mswindows.get_process_threads(self.pid)
        retlist = []
        for thread_id, utime, stime in rawlist:
            ntuple = nt_thread(thread_id, utime, stime)
            retlist.append(ntuple)
        return retlist

    @wrap_exceptions
    def get_cpu_times(self):
        try:
            ret = _psutil_mswindows.get_process_cpu_times(self.pid)
        except OSError:
            err = sys.exc_info()[1]
            if err.errno in ACCESS_DENIED_SET:
                ret = _psutil_mswindows.get_process_cpu_times_2(self.pid)
            else:
                raise
        return nt_cputimes(*ret)

    @wrap_exceptions
    def suspend_process(self):
        return _psutil_mswindows.suspend_process(self.pid)

    @wrap_exceptions
    def resume_process(self):
        return _psutil_mswindows.resume_process(self.pid)

    @wrap_exceptions
    def get_process_cwd(self):
        if self.pid in (0, 4):
            raise AccessDenied(self.pid, self._process_name)
        # return a normalized pathname since the native C function appends
        # "\\" at the and of the path
        path = _psutil_mswindows.get_process_cwd(self.pid)
        return os.path.normpath(path)

    @wrap_exceptions
    def get_open_files(self):
        if self.pid in (0, 4):
            return []
        retlist = []
        # Filenames come in in native format like:
        # "\Device\HarddiskVolume1\Windows\systemew\file.txt"
        # Convert the first part in the corresponding drive letter
        # (e.g. "C:\") by using Windows's QueryDosDevice()
        raw_file_names = _psutil_mswindows.get_process_open_files(self.pid)
        for file in raw_file_names:
            file = _convert_raw_path(file)
            if isfile_strict(file) and file not in retlist:
                ntuple = nt_openfile(file, -1)
                retlist.append(ntuple)
        return retlist

    @wrap_exceptions
    def get_connections(self, kind='inet'):
        if kind not in conn_tmap:
            raise ValueError("invalid %r kind argument; choose between %s"
                             % (kind, ', '.join([repr(x) for x in conn_tmap])))
        families, types = conn_tmap[kind]
        ret = _psutil_mswindows.get_process_connections(self.pid, families, types)
        return [nt_connection(*conn) for conn in ret]

    @wrap_exceptions
    def get_process_nice(self):
        return _psutil_mswindows.get_process_priority(self.pid)

    @wrap_exceptions
    def set_process_nice(self, value):
        return _psutil_mswindows.set_process_priority(self.pid, value)

    @wrap_exceptions
    def get_process_io_counters(self):
        try:
            ret = _psutil_mswindows.get_process_io_counters(self.pid)
        except OSError:
            err = sys.exc_info()[1]
            if err.errno in ACCESS_DENIED_SET:
                ret = _psutil_mswindows.get_process_io_counters_2(self.pid)
            else:
                raise
        return nt_io(*ret)

    @wrap_exceptions
    def get_process_status(self):
        suspended = _psutil_mswindows.is_process_suspended(self.pid)
        if suspended:
            return STATUS_STOPPED
        else:
            return STATUS_RUNNING

    @wrap_exceptions
    def get_process_cpu_affinity(self):
        from_bitmask = lambda x: [i for i in xrange(64) if (1 << i) & x]
        bitmask = _psutil_mswindows.get_process_cpu_affinity(self.pid)
        return from_bitmask(bitmask)

    @wrap_exceptions
    def set_process_cpu_affinity(self, value):
        def to_bitmask(l):
            if not l:
                raise ValueError("invalid argument %r" % l)
            out = 0
            for b in l:
                if not isinstance(b, (int, long)) or b < 0:
                    raise ValueError("invalid argument %r" % b)
                out |= 2**b
            return out

        # SetProcessAffinityMask() states that ERROR_INVALID_PARAMETER
        # is returned for an invalid CPU but this seems not to be true,
        # therefore we check CPUs validy beforehand.
        allcpus = list(range(len(get_system_per_cpu_times())))
        for cpu in value:
            if cpu not in allcpus:
                raise ValueError("invalid CPU %i" % cpu)

        bitmask = to_bitmask(value)
        _psutil_mswindows.set_process_cpu_affinity(self.pid, bitmask)

    @wrap_exceptions
    def get_num_handles(self):
        try:
            return _psutil_mswindows.get_process_num_handles(self.pid)
        except OSError:
            err = sys.exc_info()[1]
            if err.errno in ACCESS_DENIED_SET:
                return _psutil_mswindows.get_process_num_handles_2(self.pid)
            raise

    @wrap_exceptions
    def get_num_ctx_switches(self):
        return nt_ctxsw(*_psutil_mswindows.get_process_num_ctx_switches(self.pid))


"""Windows-specific implementation of process utilities with direct WinAPI.

This file is meant to be used by process.py
"""

#-----------------------------------------------------------------------------
#  Copyright (C) 2010-2011  The IPython Development Team
#
#  Distributed under the terms of the BSD License.  The full license is in
#  the file COPYING, distributed as part of this software.
#-----------------------------------------------------------------------------

from __future__ import print_function

# stdlib
import os, sys, time, threading
import ctypes, msvcrt

# Win32 API types needed for the API calls
from ctypes import POINTER
from ctypes.wintypes import HANDLE, HLOCAL, LPVOID, WORD, DWORD, BOOL, \
        ULONG, LPCWSTR
LPDWORD = POINTER(DWORD)
LPHANDLE = POINTER(HANDLE)
ULONG_PTR = POINTER(ULONG)
class SECURITY_ATTRIBUTES(ctypes.Structure):
    _fields_ = [("nLength", DWORD),
                ("lpSecurityDescriptor", LPVOID),
                ("bInheritHandle", BOOL)]
LPSECURITY_ATTRIBUTES = POINTER(SECURITY_ATTRIBUTES)
class STARTUPINFO(ctypes.Structure):
    _fields_ = [("cb", DWORD),
                ("lpReserved", LPCWSTR),
                ("lpDesktop", LPCWSTR),
                ("lpTitle", LPCWSTR),
                ("dwX", DWORD),
                ("dwY", DWORD),
                ("dwXSize", DWORD),
                ("dwYSize", DWORD),
                ("dwXCountChars", DWORD),
                ("dwYCountChars", DWORD),
                ("dwFillAttribute", DWORD),
                ("dwFlags", DWORD),
                ("wShowWindow", WORD),
                ("cbReserved2", WORD),
                ("lpReserved2", LPVOID),
                ("hStdInput", HANDLE),
                ("hStdOutput", HANDLE),
                ("hStdError", HANDLE)]
LPSTARTUPINFO = POINTER(STARTUPINFO)
class PROCESS_INFORMATION(ctypes.Structure):
    _fields_ = [("hProcess", HANDLE),
                ("hThread", HANDLE),
                ("dwProcessId", DWORD),
                ("dwThreadId", DWORD)]
LPPROCESS_INFORMATION = POINTER(PROCESS_INFORMATION)

# Win32 API constants needed
ERROR_HANDLE_EOF = 38
ERROR_BROKEN_PIPE = 109
ERROR_NO_DATA = 232
HANDLE_FLAG_INHERIT = 0x0001
STARTF_USESTDHANDLES = 0x0100
CREATE_SUSPENDED = 0x0004
CREATE_NEW_CONSOLE = 0x0010
CREATE_NO_WINDOW = 0x08000000
STILL_ACTIVE = 259
WAIT_TIMEOUT = 0x0102
WAIT_FAILED = 0xFFFFFFFF
INFINITE = 0xFFFFFFFF
DUPLICATE_SAME_ACCESS = 0x00000002
ENABLE_ECHO_INPUT = 0x0004
ENABLE_LINE_INPUT = 0x0002
ENABLE_PROCESSED_INPUT = 0x0001

# Win32 API functions needed
GetLastError = ctypes.windll.kernel32.GetLastError
GetLastError.argtypes = []
GetLastError.restype = DWORD

CreateFile = ctypes.windll.kernel32.CreateFileW
CreateFile.argtypes = [LPCWSTR, DWORD, DWORD, LPVOID, DWORD, DWORD, HANDLE]
CreateFile.restype = HANDLE

CreatePipe = ctypes.windll.kernel32.CreatePipe
CreatePipe.argtypes = [POINTER(HANDLE), POINTER(HANDLE),
        LPSECURITY_ATTRIBUTES, DWORD]
CreatePipe.restype = BOOL

CreateProcess = ctypes.windll.kernel32.CreateProcessW
CreateProcess.argtypes = [LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES,
        LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCWSTR, LPSTARTUPINFO,
        LPPROCESS_INFORMATION]
CreateProcess.restype = BOOL

GetExitCodeProcess = ctypes.windll.kernel32.GetExitCodeProcess
GetExitCodeProcess.argtypes = [HANDLE, LPDWORD]
GetExitCodeProcess.restype = BOOL

GetCurrentProcess = ctypes.windll.kernel32.GetCurrentProcess
GetCurrentProcess.argtypes = []
GetCurrentProcess.restype = HANDLE

ResumeThread = ctypes.windll.kernel32.ResumeThread
ResumeThread.argtypes = [HANDLE]
ResumeThread.restype = DWORD

ReadFile = ctypes.windll.kernel32.ReadFile
ReadFile.argtypes = [HANDLE, LPVOID, DWORD, LPDWORD, LPVOID]
ReadFile.restype = BOOL

WriteFile = ctypes.windll.kernel32.WriteFile
WriteFile.argtypes = [HANDLE, LPVOID, DWORD, LPDWORD, LPVOID]
WriteFile.restype = BOOL

GetConsoleMode = ctypes.windll.kernel32.GetConsoleMode
GetConsoleMode.argtypes = [HANDLE, LPDWORD]
GetConsoleMode.restype = BOOL

SetConsoleMode = ctypes.windll.kernel32.SetConsoleMode
SetConsoleMode.argtypes = [HANDLE, DWORD]
SetConsoleMode.restype = BOOL

FlushConsoleInputBuffer = ctypes.windll.kernel32.FlushConsoleInputBuffer
FlushConsoleInputBuffer.argtypes = [HANDLE]
FlushConsoleInputBuffer.restype = BOOL

WaitForSingleObject = ctypes.windll.kernel32.WaitForSingleObject
WaitForSingleObject.argtypes = [HANDLE, DWORD]
WaitForSingleObject.restype = DWORD

DuplicateHandle = ctypes.windll.kernel32.DuplicateHandle
DuplicateHandle.argtypes = [HANDLE, HANDLE, HANDLE, LPHANDLE,
        DWORD, BOOL, DWORD]
DuplicateHandle.restype = BOOL

SetHandleInformation = ctypes.windll.kernel32.SetHandleInformation
SetHandleInformation.argtypes = [HANDLE, DWORD, DWORD]
SetHandleInformation.restype = BOOL

CloseHandle = ctypes.windll.kernel32.CloseHandle
CloseHandle.argtypes = [HANDLE]
CloseHandle.restype = BOOL

CommandLineToArgvW = ctypes.windll.shell32.CommandLineToArgvW
CommandLineToArgvW.argtypes = [LPCWSTR, POINTER(ctypes.c_int)]
CommandLineToArgvW.restype = POINTER(LPCWSTR)

LocalFree = ctypes.windll.kernel32.LocalFree
LocalFree.argtypes = [HLOCAL]
LocalFree.restype = HLOCAL

class AvoidUNCPath(object):
    """A context manager to protect command execution from UNC paths.

    In the Win32 API, commands can't be invoked with the cwd being a UNC path.
    This context manager temporarily changes directory to the 'C:' drive on
    entering, and restores the original working directory on exit.

    The context manager returns the starting working directory *if* it made a
    change and None otherwise, so that users can apply the necessary adjustment
    to their system calls in the event of a change.

    Example
    -------
    ::
        cmd = 'dir'
        with AvoidUNCPath() as path:
            if path is not None:
                cmd = '"pushd %s &&"%s' % (path, cmd)
            os.system(cmd)
    """
    def __enter__(self):
        self.path = os.getcwdu()
        self.is_unc_path = self.path.startswith(r"\\")
        if self.is_unc_path:
            # change to c drive (as cmd.exe cannot handle UNC addresses)
            os.chdir("C:")
            return self.path
        else:
            # We return None to signal that there was no change in the working
            # directory
            return None

    def __exit__(self, exc_type, exc_value, traceback):
        if self.is_unc_path:
            os.chdir(self.path)

class Win32ShellCommandController(object):
    """Runs a shell command in a 'with' context.

    This implementation is Win32-specific.

    Example:
        # Runs the command interactively with default console stdin/stdout
        with ShellCommandController('python -i') as scc:
            scc.run()

        # Runs the command using the provided functions for stdin/stdout
        def my_stdout_func(s):
            # print or save the string 's'
            write_to_stdout(s)
        def my_stdin_func():
            # If input is available, return it as a string.
            if input_available():
                return get_input()
            # If no input available, return None after a short delay to
            # keep from blocking.
            else:
                time.sleep(0.01)
                return None

        with ShellCommandController('python -i') as scc:
            scc.run(my_stdout_func, my_stdin_func)
    """

    def __init__(self, cmd, mergeout = True):
        """Initializes the shell command controller.

        The cmd is the program to execute, and mergeout is
        whether to blend stdout and stderr into one output
        in stdout. Merging them together in this fashion more
        reliably keeps stdout and stderr in the correct order
        especially for interactive shell usage.
        """
        self.cmd = cmd
        self.mergeout = mergeout

    def __enter__(self):
        cmd = self.cmd
        mergeout = self.mergeout

        self.hstdout, self.hstdin, self.hstderr = None, None, None
        self.piProcInfo = None
        try:
            p_hstdout, c_hstdout, p_hstderr, \
                    c_hstderr, p_hstdin, c_hstdin = [None]*6

            # SECURITY_ATTRIBUTES with inherit handle set to True
            saAttr = SECURITY_ATTRIBUTES()
            saAttr.nLength = ctypes.sizeof(saAttr)
            saAttr.bInheritHandle = True
            saAttr.lpSecurityDescriptor = None

            def create_pipe(uninherit):
                """Creates a Windows pipe, which consists of two handles.

                The 'uninherit' parameter controls which handle is not
                inherited by the child process.
                """
                handles = HANDLE(), HANDLE()
                if not CreatePipe(ctypes.byref(handles[0]),
                            ctypes.byref(handles[1]), ctypes.byref(saAttr), 0):
                    raise ctypes.WinError()
                if not SetHandleInformation(handles[uninherit],
                            HANDLE_FLAG_INHERIT, 0):
                    raise ctypes.WinError()
                return handles[0].value, handles[1].value

            p_hstdout, c_hstdout = create_pipe(uninherit=0)
            # 'mergeout' signals that stdout and stderr should be merged.
            # We do that by using one pipe for both of them.
            if mergeout:
                c_hstderr = HANDLE()
                if not DuplicateHandle(GetCurrentProcess(), c_hstdout,
                                GetCurrentProcess(), ctypes.byref(c_hstderr),
                                0, True, DUPLICATE_SAME_ACCESS):
                    raise ctypes.WinError()
            else:
                p_hstderr, c_hstderr = create_pipe(uninherit=0)
            c_hstdin,  p_hstdin  = create_pipe(uninherit=1)

            # Create the process object
            piProcInfo = PROCESS_INFORMATION()
            siStartInfo = STARTUPINFO()
            siStartInfo.cb = ctypes.sizeof(siStartInfo)
            siStartInfo.hStdInput = c_hstdin
            siStartInfo.hStdOutput = c_hstdout
            siStartInfo.hStdError = c_hstderr
            siStartInfo.dwFlags = STARTF_USESTDHANDLES
            dwCreationFlags = CREATE_SUSPENDED | CREATE_NO_WINDOW # | CREATE_NEW_CONSOLE

            if not CreateProcess(None,
                    u"cmd.exe /c " + cmd,
                    None, None, True, dwCreationFlags,
                    None, None, ctypes.byref(siStartInfo),
                    ctypes.byref(piProcInfo)):
                raise ctypes.WinError()

            # Close this process's versions of the child handles
            CloseHandle(c_hstdin)
            c_hstdin = None
            CloseHandle(c_hstdout)
            c_hstdout = None
            if c_hstderr != None:
                CloseHandle(c_hstderr)
                c_hstderr = None

            # Transfer ownership of the parent handles to the object
            self.hstdin = p_hstdin
            p_hstdin = None
            self.hstdout = p_hstdout
            p_hstdout = None
            if not mergeout:
                self.hstderr = p_hstderr
                p_hstderr = None
            self.piProcInfo = piProcInfo

        finally:
            if p_hstdin:
                CloseHandle(p_hstdin)
            if c_hstdin:
                CloseHandle(c_hstdin)
            if p_hstdout:
                CloseHandle(p_hstdout)
            if c_hstdout:
                CloseHandle(c_hstdout)
            if p_hstderr:
                CloseHandle(p_hstderr)
            if c_hstderr:
                CloseHandle(c_hstderr)

        return self

    def _stdin_thread(self, handle, hprocess, func, stdout_func):
        exitCode = DWORD()
        bytesWritten = DWORD(0)
        while True:
            #print("stdin thread loop start")
            # Get the input string (may be bytes or unicode)
            data = func()

            # None signals to poll whether the process has exited
            if data is None:
                #print("checking for process completion")
                if not GetExitCodeProcess(hprocess, ctypes.byref(exitCode)):
                    raise ctypes.WinError()
                if exitCode.value != STILL_ACTIVE:
                    return
                # TESTING: Does zero-sized writefile help?
                if not WriteFile(handle, "", 0,
                        ctypes.byref(bytesWritten), None):
                    raise ctypes.WinError()
                continue
            #print("\nGot str %s\n" % repr(data), file=sys.stderr)

            # Encode the string to the console encoding
            if isinstance(data, unicode): #FIXME: Python3
                data = data.encode('utf_8')

            # What we have now must be a string of bytes
            if not isinstance(data, str): #FIXME: Python3
                raise RuntimeError("internal stdin function string error")

            # An empty string signals EOF
            if len(data) == 0:
                return

            # In a windows console, sometimes the input is echoed,
            # but sometimes not. How do we determine when to do this?
            stdout_func(data)
            # WriteFile may not accept all the data at once.
            # Loop until everything is processed
            while len(data) != 0:
                #print("Calling writefile")
                if not WriteFile(handle, data, len(data),
                        ctypes.byref(bytesWritten), None):
                    # This occurs at exit
                    if GetLastError() == ERROR_NO_DATA:
                        return
                    raise ctypes.WinError()
                #print("Called writefile")
                data = data[bytesWritten.value:]

    def _stdout_thread(self, handle, func):
        # Allocate the output buffer
        data = ctypes.create_string_buffer(4096)
        while True:
            bytesRead = DWORD(0)
            if not ReadFile(handle, data, 4096,
                        ctypes.byref(bytesRead), None):
                le = GetLastError()
                if le == ERROR_BROKEN_PIPE:
                    return
                else:
                    raise ctypes.WinError()
            # FIXME: Python3
            s = data.value[0:bytesRead.value]
            #print("\nv: %s" % repr(s), file=sys.stderr)
            func(s.decode('utf_8', 'replace'))

    def run(self, stdout_func = None, stdin_func = None, stderr_func = None):
        """Runs the process, using the provided functions for I/O.

        The function stdin_func should return strings whenever a
        character or characters become available.
        The functions stdout_func and stderr_func are called whenever
        something is printed to stdout or stderr, respectively.
        These functions are called from different threads (but not
        concurrently, because of the GIL).
        """
        if stdout_func == None and stdin_func == None and stderr_func == None:
            return self._run_stdio()

        if stderr_func != None and self.mergeout:
            raise RuntimeError("Shell command was initiated with "
                    "merged stdin/stdout, but a separate stderr_func "
                    "was provided to the run() method")

        # Create a thread for each input/output handle
        stdin_thread = None
        threads = []
        if stdin_func:
            stdin_thread = threading.Thread(target=self._stdin_thread,
                                args=(self.hstdin, self.piProcInfo.hProcess,
                                stdin_func, stdout_func))
        threads.append(threading.Thread(target=self._stdout_thread,
                                    args=(self.hstdout, stdout_func)))
        if not self.mergeout:
            if stderr_func == None:
                stderr_func = stdout_func
            threads.append(threading.Thread(target=self._stdout_thread,
                                        args=(self.hstderr, stderr_func)))
        # Start the I/O threads and the process
        if ResumeThread(self.piProcInfo.hThread) == 0xFFFFFFFF:
            raise ctypes.WinError()
        if stdin_thread is not None:
            stdin_thread.start()
        for thread in threads:
            thread.start()
        # Wait for the process to complete
        if WaitForSingleObject(self.piProcInfo.hProcess, INFINITE) == \
                    WAIT_FAILED:
            raise ctypes.WinError()
        # Wait for the I/O threads to complete
        for thread in threads:
            thread.join()

        # Wait for the stdin thread to complete
        if stdin_thread is not None:
            stdin_thread.join()

    def _stdin_raw_nonblock(self):
        """Use the raw Win32 handle of sys.stdin to do non-blocking reads"""
        # WARNING: This is experimental, and produces inconsistent results.
        #          It's possible for the handle not to be appropriate for use
        #          with WaitForSingleObject, among other things.
        handle = msvcrt.get_osfhandle(sys.stdin.fileno())
        result = WaitForSingleObject(handle, 100)
        if result == WAIT_FAILED:
            raise ctypes.WinError()
        elif result == WAIT_TIMEOUT:
            print(".", end='')
            return None
        else:
            data = ctypes.create_string_buffer(256)
            bytesRead = DWORD(0)
            print('?', end='')

            if not ReadFile(handle, data, 256,
                        ctypes.byref(bytesRead), None):
                raise ctypes.WinError()
            # This ensures the non-blocking works with an actual console
            # Not checking the error, so the processing will still work with
            # other handle types
            FlushConsoleInputBuffer(handle)

            data = data.value
            data = data.replace('\r\n', '\n')
            data = data.replace('\r', '\n')
            print(repr(data) + " ", end='')
            return data

    def _stdin_raw_block(self):
        """Use a blocking stdin read"""
        # The big problem with the blocking read is that it doesn't
        # exit when it's supposed to in all contexts. An extra
        # key-press may be required to trigger the exit.
        try:
            data = sys.stdin.read(1)
            data = data.replace('\r', '\n')
            return data
        except WindowsError as we:
            if we.winerror == ERROR_NO_DATA:
                # This error occurs when the pipe is closed
                return None
            else:
                # Otherwise let the error propagate
                raise we

    def _stdout_raw(self, s):
        """Writes the string to stdout"""
        print(s, end='', file=sys.stdout)
        sys.stdout.flush()

    def _stderr_raw(self, s):
        """Writes the string to stdout"""
        print(s, end='', file=sys.stderr)
        sys.stderr.flush()

    def _run_stdio(self):
        """Runs the process using the system standard I/O.

        IMPORTANT: stdin needs to be asynchronous, so the Python
                   sys.stdin object is not used. Instead,
                   msvcrt.kbhit/getwch are used asynchronously.
        """
        # Disable Line and Echo mode
        #lpMode = DWORD()
        #handle = msvcrt.get_osfhandle(sys.stdin.fileno())
        #if GetConsoleMode(handle, ctypes.byref(lpMode)):
        #    set_console_mode = True
        #    if not SetConsoleMode(handle, lpMode.value &
        #            ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT)):
        #        raise ctypes.WinError()

        if self.mergeout:
            return self.run(stdout_func = self._stdout_raw,
                    stdin_func = self._stdin_raw_block)
        else:
            return self.run(stdout_func = self._stdout_raw,
                    stdin_func = self._stdin_raw_block,
                    stderr_func = self._stderr_raw)

        # Restore the previous console mode
        #if set_console_mode:
        #    if not SetConsoleMode(handle, lpMode.value):
        #        raise ctypes.WinError()

    def __exit__(self, exc_type, exc_value, traceback):
        if self.hstdin:
            CloseHandle(self.hstdin)
            self.hstdin = None
        if self.hstdout:
            CloseHandle(self.hstdout)
            self.hstdout = None
        if self.hstderr:
            CloseHandle(self.hstderr)
            self.hstderr = None
        if self.piProcInfo != None:
            CloseHandle(self.piProcInfo.hProcess)
            CloseHandle(self.piProcInfo.hThread)
            self.piProcInfo = None

def system(cmd):
    """Win32 version of os.system() that works with network shares.

    Note that this implementation returns None, as meant for use in IPython.

    Parameters
    ----------
    cmd : str
      A command to be executed in the system shell.

    Returns
    -------
    None : we explicitly do NOT return the subprocess status code, as this
    utility is meant to be used extensively in IPython, where any return value
    would trigger :func:`sys.displayhook` calls.
    """
    with AvoidUNCPath() as path:
        if path is not None:
            cmd = '"pushd %s &&"%s' % (path, cmd)
        with Win32ShellCommandController(cmd) as scc:
            scc.run()

if __name__ == "__main__":
    print("Test starting!")
    #system("cmd")
    system("python -i")
    print("Test finished!")


"""The Qt MainWindow for the QtConsole

This is a tabbed pseudo-terminal of IPython sessions, with a menu bar for
common actions.

Authors:

* Evan Patterson
* Min RK
* Erik Tollerud
* Fernando Perez
* Bussonnier Matthias
* Thomas Kluyver
* Paul Ivanov

"""

#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------

# stdlib imports
import sys
import re
import webbrowser
import ast
from threading import Thread

# System library imports
from IPython.external.qt import QtGui,QtCore

def background(f):
    """call a function in a simple thread, to prevent blocking"""
    t = Thread(target=f)
    t.start()
    return t

#-----------------------------------------------------------------------------
# Classes
#-----------------------------------------------------------------------------

class MainWindow(QtGui.QMainWindow):

    #---------------------------------------------------------------------------
    # 'object' interface
    #---------------------------------------------------------------------------

    _magic_menu_dict = {}

    def __init__(self, app,
                    confirm_exit=True,
                    new_frontend_factory=None, slave_frontend_factory=None,
                ):
        """ Create a tabbed MainWindow for managing IPython FrontendWidgets

        Parameters
        ----------

        app : reference to QApplication parent
        confirm_exit : bool, optional
            Whether we should prompt on close of tabs
        new_frontend_factory : callable
            A callable that returns a new IPythonWidget instance, attached to
            its own running kernel.
        slave_frontend_factory : callable
            A callable that takes an existing IPythonWidget, and  returns a new
            IPythonWidget instance, attached to the same kernel.
        """

        super(MainWindow, self).__init__()
        self._kernel_counter = 0
        self._app = app
        self.confirm_exit = confirm_exit
        self.new_frontend_factory = new_frontend_factory
        self.slave_frontend_factory = slave_frontend_factory

        self.tab_widget = QtGui.QTabWidget(self)
        self.tab_widget.setDocumentMode(True)
        self.tab_widget.setTabsClosable(True)
        self.tab_widget.tabCloseRequested[int].connect(self.close_tab)

        self.setCentralWidget(self.tab_widget)
        # hide tab bar at first, since we have no tabs:
        self.tab_widget.tabBar().setVisible(False)
        # prevent focus in tab bar
        self.tab_widget.setFocusPolicy(QtCore.Qt.NoFocus)

    def update_tab_bar_visibility(self):
        """ update visibility of the tabBar depending of the number of tab

        0 or 1 tab, tabBar hidden
        2+ tabs, tabBar visible

        send a self.close if number of tab ==0

        need to be called explicitly, or be connected to tabInserted/tabRemoved
        """
        if self.tab_widget.count() <= 1:
            self.tab_widget.tabBar().setVisible(False)
        else:
            self.tab_widget.tabBar().setVisible(True)
        if self.tab_widget.count()==0 :
            self.close()

    @property
    def next_kernel_id(self):
        """constantly increasing counter for kernel IDs"""
        c = self._kernel_counter
        self._kernel_counter += 1
        return c

    @property
    def active_frontend(self):
        return self.tab_widget.currentWidget()

    def create_tab_with_new_frontend(self):
        """create a new frontend and attach it to a new tab"""
        widget = self.new_frontend_factory()
        self.add_tab_with_frontend(widget)

    def create_tab_with_current_kernel(self):
        """create a new frontend attached to the same kernel as the current tab"""
        current_widget = self.tab_widget.currentWidget()
        current_widget_index = self.tab_widget.indexOf(current_widget)
        current_widget_name = self.tab_widget.tabText(current_widget_index)
        widget = self.slave_frontend_factory(current_widget)
        if 'slave' in current_widget_name:
            # don't keep stacking slaves
            name = current_widget_name
        else:
            name = '(%s) slave' % current_widget_name
        self.add_tab_with_frontend(widget,name=name)

    def close_tab(self,current_tab):
        """ Called when you need to try to close a tab.

        It takes the number of the tab to be closed as argument, or a reference
        to the widget inside this tab
        """

        # let's be sure "tab" and "closing widget" are respectively the index
        # of the tab to close and a reference to the frontend to close
        if type(current_tab) is not int :
            current_tab = self.tab_widget.indexOf(current_tab)
        closing_widget=self.tab_widget.widget(current_tab)

        # when trying to be closed, widget might re-send a request to be
        # closed again, but will be deleted when event will be processed. So
        # need to check that widget still exists and skip if not. One example
        # of this is when 'exit' is sent in a slave tab. 'exit' will be
        # re-sent by this function on the master widget, which ask all slave
        # widgets to exit
        if closing_widget==None:
            return

        #get a list of all slave widgets on the same kernel.
        slave_tabs = self.find_slave_widgets(closing_widget)

        keepkernel = None #Use the prompt by default
        if hasattr(closing_widget,'_keep_kernel_on_exit'): #set by exit magic
            keepkernel = closing_widget._keep_kernel_on_exit
            # If signal sent by exit magic (_keep_kernel_on_exit, exist and not None)
            # we set local slave tabs._hidden to True to avoid prompting for kernel
            # restart when they get the signal. and then "forward" the 'exit'
            # to the main window
            if keepkernel is not None:
                for tab in slave_tabs:
                    tab._hidden = True
                if closing_widget in slave_tabs:
                    try :
                        self.find_master_tab(closing_widget).execute('exit')
                    except AttributeError:
                        self.log.info("Master already closed or not local, closing only current tab")
                        self.tab_widget.removeTab(current_tab)
                    self.update_tab_bar_visibility()
                    return

        kernel_manager = closing_widget.kernel_manager

        if keepkernel is None and not closing_widget._confirm_exit:
            # don't prompt, just terminate the kernel if we own it
            # or leave it alone if we don't
            keepkernel = closing_widget._existing
        if keepkernel is None: #show prompt
            if kernel_manager and kernel_manager.channels_running:
                title = self.window().windowTitle()
                cancel = QtGui.QMessageBox.Cancel
                okay = QtGui.QMessageBox.Ok
                if closing_widget._may_close:
                    msg = "You are closing the tab : "+'"'+self.tab_widget.tabText(current_tab)+'"'
                    info = "Would you like to quit the Kernel and close all attached Consoles as well?"
                    justthis = QtGui.QPushButton("&No, just this Tab", self)
                    justthis.setShortcut('N')
                    closeall = QtGui.QPushButton("&Yes, close all", self)
                    closeall.setShortcut('Y')
                    # allow ctrl-d ctrl-d exit, like in terminal
                    closeall.setShortcut('Ctrl+D')
                    box = QtGui.QMessageBox(QtGui.QMessageBox.Question,
                                            title, msg)
                    box.setInformativeText(info)
                    box.addButton(cancel)
                    box.addButton(justthis, QtGui.QMessageBox.NoRole)
                    box.addButton(closeall, QtGui.QMessageBox.YesRole)
                    box.setDefaultButton(closeall)
                    box.setEscapeButton(cancel)
                    pixmap = QtGui.QPixmap(self._app.icon.pixmap(QtCore.QSize(64,64)))
                    box.setIconPixmap(pixmap)
                    reply = box.exec_()
                    if reply == 1: # close All
                        for slave in slave_tabs:
                            background(slave.kernel_manager.stop_channels)
                            self.tab_widget.removeTab(self.tab_widget.indexOf(slave))
                        closing_widget.execute("exit")
                        self.tab_widget.removeTab(current_tab)
                        background(kernel_manager.stop_channels)
                    elif reply == 0: # close Console
                        if not closing_widget._existing:
                            # Have kernel: don't quit, just close the tab
                            closing_widget.execute("exit True")
                        self.tab_widget.removeTab(current_tab)
                        background(kernel_manager.stop_channels)
                else:
                    reply = QtGui.QMessageBox.question(self, title,
                        "Are you sure you want to close this Console?"+
                        "\nThe Kernel and other Consoles will remain active.",
                        okay|cancel,
                        defaultButton=okay
                        )
                    if reply == okay:
                        self.tab_widget.removeTab(current_tab)
        elif keepkernel: #close console but leave kernel running (no prompt)
            self.tab_widget.removeTab(current_tab)
            background(kernel_manager.stop_channels)
        else: #close console and kernel (no prompt)
            self.tab_widget.removeTab(current_tab)
            if kernel_manager and kernel_manager.channels_running:
                for slave in slave_tabs:
                    background(slave.kernel_manager.stop_channels)
                    self.tab_widget.removeTab(self.tab_widget.indexOf(slave))
                kernel_manager.shutdown_kernel()
                background(kernel_manager.stop_channels)

        self.update_tab_bar_visibility()

    def add_tab_with_frontend(self,frontend,name=None):
        """ insert a tab with a given frontend in the tab bar, and give it a name

        """
        if not name:
            name = 'kernel %i' % self.next_kernel_id
        self.tab_widget.addTab(frontend,name)
        self.update_tab_bar_visibility()
        self.make_frontend_visible(frontend)
        frontend.exit_requested.connect(self.close_tab)

    def next_tab(self):
        self.tab_widget.setCurrentIndex((self.tab_widget.currentIndex()+1))

    def prev_tab(self):
        self.tab_widget.setCurrentIndex((self.tab_widget.currentIndex()-1))

    def make_frontend_visible(self,frontend):
        widget_index=self.tab_widget.indexOf(frontend)
        if widget_index > 0 :
            self.tab_widget.setCurrentIndex(widget_index)

    def find_master_tab(self,tab,as_list=False):
        """
        Try to return the frontend that owns the kernel attached to the given widget/tab.

            Only finds frontend owned by the current application. Selection
            based on port of the kernel might be inaccurate if several kernel
            on different ip use same port number.

            This function does the conversion tabNumber/widget if needed.
            Might return None if no master widget (non local kernel)
            Will crash IPython if more than 1 masterWidget

            When asList set to True, always return a list of widget(s) owning
            the kernel. The list might be empty or containing several Widget.
        """

        #convert from/to int/richIpythonWidget if needed
        if isinstance(tab, int):
            tab = self.tab_widget.widget(tab)
        km=tab.kernel_manager

        #build list of all widgets
        widget_list = [self.tab_widget.widget(i) for i in range(self.tab_widget.count())]

        # widget that are candidate to be the owner of the kernel does have all the same port of the curent widget
        # And should have a _may_close attribute
        filtered_widget_list = [ widget for widget in widget_list if
                                widget.kernel_manager.connection_file == km.connection_file and
                                hasattr(widget,'_may_close') ]
        # the master widget is the one that may close the kernel
        master_widget= [ widget for widget in filtered_widget_list if widget._may_close]
        if as_list:
            return master_widget
        assert(len(master_widget)<=1 )
        if len(master_widget)==0:
            return None

        return master_widget[0]

    def find_slave_widgets(self,tab):
        """return all the frontends that do not own the kernel attached to the given widget/tab.

            Only find frontends owned by the current application. Selection
            based on connection file of the kernel.

            This function does the conversion tabNumber/widget if needed.
        """
        #convert from/to int/richIpythonWidget if needed
        if isinstance(tab, int):
            tab = self.tab_widget.widget(tab)
        km=tab.kernel_manager

        #build list of all widgets
        widget_list = [self.tab_widget.widget(i) for i in range(self.tab_widget.count())]

        # widget that are candidate not to be the owner of the kernel does have all the same port of the curent widget
        filtered_widget_list = ( widget for widget in widget_list if
                                widget.kernel_manager.connection_file == km.connection_file)
        # Get a list of all widget owning the same kernel and removed it from
        # the previous cadidate. (better using sets ?)
        master_widget_list = self.find_master_tab(tab, as_list=True)
        slave_list = [widget for widget in filtered_widget_list if widget not in master_widget_list]

        return slave_list

    # Populate the menu bar with common actions and shortcuts
    def add_menu_action(self, menu, action, defer_shortcut=False):
        """Add action to menu as well as self

        So that when the menu bar is invisible, its actions are still available.

        If defer_shortcut is True, set the shortcut context to widget-only,
        where it will avoid conflict with shortcuts already bound to the
        widgets themselves.
        """
        menu.addAction(action)
        self.addAction(action)

        if defer_shortcut:
            action.setShortcutContext(QtCore.Qt.WidgetShortcut)

    def init_menu_bar(self):
        #create menu in the order they should appear in the menu bar
        self.init_file_menu()
        self.init_edit_menu()
        self.init_view_menu()
        self.init_kernel_menu()
        self.init_magic_menu()
        self.init_window_menu()
        self.init_help_menu()

    def init_file_menu(self):
        self.file_menu = self.menuBar().addMenu("&File")

        self.new_kernel_tab_act = QtGui.QAction("New Tab with &New kernel",
            self,
            shortcut="Ctrl+T",
            triggered=self.create_tab_with_new_frontend)
        self.add_menu_action(self.file_menu, self.new_kernel_tab_act)

        self.slave_kernel_tab_act = QtGui.QAction("New Tab with Sa&me kernel",
            self,
            shortcut="Ctrl+Shift+T",
            triggered=self.create_tab_with_current_kernel)
        self.add_menu_action(self.file_menu, self.slave_kernel_tab_act)

        self.file_menu.addSeparator()

        self.close_action=QtGui.QAction("&Close Tab",
            self,
            shortcut=QtGui.QKeySequence.Close,
            triggered=self.close_active_frontend
            )
        self.add_menu_action(self.file_menu, self.close_action)

        self.export_action=QtGui.QAction("&Save to HTML/XHTML",
            self,
            shortcut=QtGui.QKeySequence.Save,
            triggered=self.export_action_active_frontend
            )
        self.add_menu_action(self.file_menu, self.export_action, True)

        self.file_menu.addSeparator()

        printkey = QtGui.QKeySequence(QtGui.QKeySequence.Print)
        if printkey.matches("Ctrl+P") and sys.platform != 'darwin':
            # Only override the default if there is a collision.
            # Qt ctrl = cmd on OSX, so the match gets a false positive on OSX.
            printkey = "Ctrl+Shift+P"
        self.print_action = QtGui.QAction("&Print",
            self,
            shortcut=printkey,
            triggered=self.print_action_active_frontend)
        self.add_menu_action(self.file_menu, self.print_action, True)

        if sys.platform != 'darwin':
            # OSX always has Quit in the Application menu, only add it
            # to the File menu elsewhere.

            self.file_menu.addSeparator()

            self.quit_action = QtGui.QAction("&Quit",
                self,
                shortcut=QtGui.QKeySequence.Quit,
                triggered=self.close,
            )
            self.add_menu_action(self.file_menu, self.quit_action)

    def init_edit_menu(self):
        self.edit_menu = self.menuBar().addMenu("&Edit")

        self.undo_action = QtGui.QAction("&Undo",
            self,
            shortcut=QtGui.QKeySequence.Undo,
            statusTip="Undo last action if possible",
            triggered=self.undo_active_frontend
            )
        self.add_menu_action(self.edit_menu, self.undo_action)

        self.redo_action = QtGui.QAction("&Redo",
            self,
            shortcut=QtGui.QKeySequence.Redo,
            statusTip="Redo last action if possible",
            triggered=self.redo_active_frontend)
        self.add_menu_action(self.edit_menu, self.redo_action)

        self.edit_menu.addSeparator()

        self.cut_action = QtGui.QAction("&Cut",
            self,
            shortcut=QtGui.QKeySequence.Cut,
            triggered=self.cut_active_frontend
            )
        self.add_menu_action(self.edit_menu, self.cut_action, True)

        self.copy_action = QtGui.QAction("&Copy",
            self,
            shortcut=QtGui.QKeySequence.Copy,
            triggered=self.copy_active_frontend
            )
        self.add_menu_action(self.edit_menu, self.copy_action, True)

        self.copy_raw_action = QtGui.QAction("Copy (&Raw Text)",
            self,
            shortcut="Ctrl+Shift+C",
            triggered=self.copy_raw_active_frontend
            )
        self.add_menu_action(self.edit_menu, self.copy_raw_action, True)

        self.paste_action = QtGui.QAction("&Paste",
            self,
            shortcut=QtGui.QKeySequence.Paste,
            triggered=self.paste_active_frontend
            )
        self.add_menu_action(self.edit_menu, self.paste_action, True)

        self.edit_menu.addSeparator()

        selectall = QtGui.QKeySequence(QtGui.QKeySequence.SelectAll)
        if selectall.matches("Ctrl+A") and sys.platform != 'darwin':
            # Only override the default if there is a collision.
            # Qt ctrl = cmd on OSX, so the match gets a false positive on OSX.
            selectall = "Ctrl+Shift+A"
        self.select_all_action = QtGui.QAction("Select &All",
            self,
            shortcut=selectall,
            triggered=self.select_all_active_frontend
            )
        self.add_menu_action(self.edit_menu, self.select_all_action, True)

    def init_view_menu(self):
        self.view_menu = self.menuBar().addMenu("&View")

        if sys.platform != 'darwin':
            # disable on OSX, where there is always a menu bar
            self.toggle_menu_bar_act = QtGui.QAction("Toggle &Menu Bar",
                self,
                shortcut="Ctrl+Shift+M",
                statusTip="Toggle visibility of menubar",
                triggered=self.toggle_menu_bar)
            self.add_menu_action(self.view_menu, self.toggle_menu_bar_act)

        fs_key = "Ctrl+Meta+F" if sys.platform == 'darwin' else "F11"
        self.full_screen_act = QtGui.QAction("&Full Screen",
            self,
            shortcut=fs_key,
            statusTip="Toggle between Fullscreen and Normal Size",
            triggered=self.toggleFullScreen)
        self.add_menu_action(self.view_menu, self.full_screen_act)

        self.view_menu.addSeparator()

        self.increase_font_size = QtGui.QAction("Zoom &In",
            self,
            shortcut=QtGui.QKeySequence.ZoomIn,
            triggered=self.increase_font_size_active_frontend
            )
        self.add_menu_action(self.view_menu, self.increase_font_size, True)

        self.decrease_font_size = QtGui.QAction("Zoom &Out",
            self,
            shortcut=QtGui.QKeySequence.ZoomOut,
            triggered=self.decrease_font_size_active_frontend
            )
        self.add_menu_action(self.view_menu, self.decrease_font_size, True)

        self.reset_font_size = QtGui.QAction("Zoom &Reset",
            self,
            shortcut="Ctrl+0",
            triggered=self.reset_font_size_active_frontend
            )
        self.add_menu_action(self.view_menu, self.reset_font_size, True)

        self.view_menu.addSeparator()

        self.clear_action = QtGui.QAction("&Clear Screen",
            self,
            shortcut='Ctrl+L',
            statusTip="Clear the console",
            triggered=self.clear_magic_active_frontend)
        self.add_menu_action(self.view_menu, self.clear_action)

    def init_kernel_menu(self):
        self.kernel_menu = self.menuBar().addMenu("&Kernel")
        # Qt on OSX maps Ctrl to Cmd, and Meta to Ctrl
        # keep the signal shortcuts to ctrl, rather than
        # platform-default like we do elsewhere.

        ctrl = "Meta" if sys.platform == 'darwin' else "Ctrl"

        self.interrupt_kernel_action = QtGui.QAction("&Interrupt current Kernel",
            self,
            triggered=self.interrupt_kernel_active_frontend,
            shortcut=ctrl+"+C",
            )
        self.add_menu_action(self.kernel_menu, self.interrupt_kernel_action)

        self.restart_kernel_action = QtGui.QAction("&Restart current Kernel",
            self,
            triggered=self.restart_kernel_active_frontend,
            shortcut=ctrl+"+.",
            )
        self.add_menu_action(self.kernel_menu, self.restart_kernel_action)

        self.kernel_menu.addSeparator()

        self.confirm_restart_kernel_action = QtGui.QAction("&Confirm kernel restart",
            self,
            checkable=True,
            checked=self.active_frontend.confirm_restart,
            triggered=self.toggle_confirm_restart_active_frontend
            )

        self.add_menu_action(self.kernel_menu, self.confirm_restart_kernel_action)
        self.tab_widget.currentChanged.connect(self.update_restart_checkbox)

    def _make_dynamic_magic(self,magic):
        """Return a function `fun` that will execute `magic` on active frontend.

        Parameters
        ----------
        magic : string
            string that will be executed as is when the returned function is called

        Returns
        -------
        fun : function
            function with no parameters, when called will execute `magic` on the
            current active frontend at call time

        See Also
        --------
        populate_all_magic_menu : generate the "All Magics..." menu

        Notes
        -----
        `fun` executes `magic` in active frontend at the moment it is triggered,
        not the active frontend at the moment it was created.

        This function is mostly used to create the "All Magics..." Menu at run time.
        """
        # need two level nested function to be sure to pass magic
        # to active frontend **at run time**.
        def inner_dynamic_magic():
            self.active_frontend.execute(magic)
        inner_dynamic_magic.__name__ = "dynamics_magic_s"
        return inner_dynamic_magic

    def populate_all_magic_menu(self, listofmagic=None):
        """Clean "All Magics..." menu and repopulate it with `listofmagic`

        Parameters
        ----------
        listofmagic : string,
            repr() of a list of strings, send back by the kernel

        Notes
        -----
        `listofmagic`is a repr() of list because it is fed with the result of
        a 'user_expression'
        """
        for k,v in self._magic_menu_dict.items():
            v.clear()
        self.all_magic_menu.clear()

        protected_magic = set(["more","less","load_ext","pycat","loadpy","load","save","psource"])
        mlist=ast.literal_eval(listofmagic)
        for magic in mlist:
            cell = (magic['type'] == 'cell')
            name = magic['name']
            mclass = magic['class']
            if cell :
                prefix='%%'
            else :
                prefix='%'
            magic_menu = self._get_magic_menu(mclass)

            if name in protected_magic:
                suffix = '?'
            else :
                suffix = ''
            pmagic = '%s%s%s'%(prefix,name,suffix)

            xaction = QtGui.QAction(pmagic,
                self,
                triggered=self._make_dynamic_magic(pmagic)
                )
            magic_menu.addAction(xaction)
            self.all_magic_menu.addAction(xaction)

    def update_all_magic_menu(self):
        """ Update the list of magics in the "All Magics..." Menu

        Request the kernel with the list of available magics and populate the
        menu with the list received back

        """
        self.active_frontend._silent_exec_callback('get_ipython().magics_manager.lsmagic_info()',
                self.populate_all_magic_menu)

    def _get_magic_menu(self,menuidentifier, menulabel=None):
        """return a submagic menu by name, and create it if needed

        parameters:
        -----------

        menulabel : str
            Label for the menu

        Will infere the menu name from the identifier at creation if menulabel not given.
        To do so you have too give menuidentifier as a CamelCassedString
        """
        menu = self._magic_menu_dict.get(menuidentifier,None)
        if not menu :
            if not menulabel:
                menulabel = re.sub("([a-zA-Z]+)([A-Z][a-z])","\g<1> \g<2>",menuidentifier)
            menu = QtGui.QMenu(menulabel,self.magic_menu)
            self._magic_menu_dict[menuidentifier]=menu
            self.magic_menu.insertMenu(self.magic_menu_separator,menu)
        return menu

    def init_magic_menu(self):
        self.magic_menu = self.menuBar().addMenu("&Magic")
        self.magic_menu_separator = self.magic_menu.addSeparator()

        self.all_magic_menu = self._get_magic_menu("AllMagics", menulabel="&All Magics...")

        # This action should usually not appear as it will be cleared when menu
        # is updated at first kernel response. Though, it is necessary when
        # connecting through X-forwarding, as in this case, the menu is not
        # auto updated, SO DO NOT DELETE.
        self.pop = QtGui.QAction("&Update All Magic Menu ",
            self, triggered=self.update_all_magic_menu)
        self.add_menu_action(self.all_magic_menu, self.pop)
        # we need to populate the 'Magic Menu' once the kernel has answer at
        # least once let's do it immediately, but it's assured to works
        self.pop.trigger()

        self.reset_action = QtGui.QAction("&Reset",
            self,
            statusTip="Clear all variables from workspace",
            triggered=self.reset_magic_active_frontend)
        self.add_menu_action(self.magic_menu, self.reset_action)

        self.history_action = QtGui.QAction("&History",
            self,
            statusTip="show command history",
            triggered=self.history_magic_active_frontend)
        self.add_menu_action(self.magic_menu, self.history_action)

        self.save_action = QtGui.QAction("E&xport History ",
            self,
            statusTip="Export History as Python File",
            triggered=self.save_magic_active_frontend)
        self.add_menu_action(self.magic_menu, self.save_action)

        self.who_action = QtGui.QAction("&Who",
            self,
            statusTip="List interactive variables",
            triggered=self.who_magic_active_frontend)
        self.add_menu_action(self.magic_menu, self.who_action)

        self.who_ls_action = QtGui.QAction("Wh&o ls",
            self,
            statusTip="Return a list of interactive variables",
            triggered=self.who_ls_magic_active_frontend)
        self.add_menu_action(self.magic_menu, self.who_ls_action)

        self.whos_action = QtGui.QAction("Who&s",
            self,
            statusTip="List interactive variables with details",
            triggered=self.whos_magic_active_frontend)
        self.add_menu_action(self.magic_menu, self.whos_action)

    def init_window_menu(self):
        self.window_menu = self.menuBar().addMenu("&Window")
        if sys.platform == 'darwin':
            # add min/maximize actions to OSX, which lacks default bindings.
            self.minimizeAct = QtGui.QAction("Mini&mize",
                self,
                shortcut="Ctrl+m",
                statusTip="Minimize the window/Restore Normal Size",
                triggered=self.toggleMinimized)
            # maximize is called 'Zoom' on OSX for some reason
            self.maximizeAct = QtGui.QAction("&Zoom",
                self,
                shortcut="Ctrl+Shift+M",
                statusTip="Maximize the window/Restore Normal Size",
                triggered=self.toggleMaximized)

            self.add_menu_action(self.window_menu, self.minimizeAct)
            self.add_menu_action(self.window_menu, self.maximizeAct)
            self.window_menu.addSeparator()

        prev_key = "Ctrl+Shift+Left" if sys.platform == 'darwin' else "Ctrl+PgUp"
        self.prev_tab_act = QtGui.QAction("Pre&vious Tab",
            self,
            shortcut=prev_key,
            statusTip="Select previous tab",
            triggered=self.prev_tab)
        self.add_menu_action(self.window_menu, self.prev_tab_act)

        next_key = "Ctrl+Shift+Right" if sys.platform == 'darwin' else "Ctrl+PgDown"
        self.next_tab_act = QtGui.QAction("Ne&xt Tab",
            self,
            shortcut=next_key,
            statusTip="Select next tab",
            triggered=self.next_tab)
        self.add_menu_action(self.window_menu, self.next_tab_act)

    def init_help_menu(self):
        # please keep the Help menu in Mac Os even if empty. It will
        # automatically contain a search field to search inside menus and
        # please keep it spelled in English, as long as Qt Doesn't support
        # a QAction.MenuRole like HelpMenuRole otherwise it will lose
        # this search field functionality

        self.help_menu = self.menuBar().addMenu("&Help")

        # Help Menu

        self.intro_active_frontend_action = QtGui.QAction("&Intro to IPython",
            self,
            triggered=self.intro_active_frontend
            )
        self.add_menu_action(self.help_menu, self.intro_active_frontend_action)

        self.quickref_active_frontend_action = QtGui.QAction("IPython &Cheat Sheet",
            self,
            triggered=self.quickref_active_frontend
            )
        self.add_menu_action(self.help_menu, self.quickref_active_frontend_action)

        self.guiref_active_frontend_action = QtGui.QAction("&Qt Console",
            self,
            triggered=self.guiref_active_frontend
            )
        self.add_menu_action(self.help_menu, self.guiref_active_frontend_action)

        self.onlineHelpAct = QtGui.QAction("Open Online &Help",
            self,
            triggered=self._open_online_help)
        self.add_menu_action(self.help_menu, self.onlineHelpAct)

    # minimize/maximize/fullscreen actions:

    def toggle_menu_bar(self):
        menu_bar = self.menuBar()
        if menu_bar.isVisible():
            menu_bar.setVisible(False)
        else:
            menu_bar.setVisible(True)

    def toggleMinimized(self):
        if not self.isMinimized():
            self.showMinimized()
        else:
            self.showNormal()

    def _open_online_help(self):
        filename="http://ipython.org/ipython-doc/stable/index.html"
        webbrowser.open(filename, new=1, autoraise=True)

    def toggleMaximized(self):
        if not self.isMaximized():
            self.showMaximized()
        else:
            self.showNormal()

    # Min/Max imizing while in full screen give a bug
    # when going out of full screen, at least on OSX
    def toggleFullScreen(self):
        if not self.isFullScreen():
            self.showFullScreen()
            if sys.platform == 'darwin':
                self.maximizeAct.setEnabled(False)
                self.minimizeAct.setEnabled(False)
        else:
            self.showNormal()
            if sys.platform == 'darwin':
                self.maximizeAct.setEnabled(True)
                self.minimizeAct.setEnabled(True)

    def close_active_frontend(self):
        self.close_tab(self.active_frontend)

    def restart_kernel_active_frontend(self):
        self.active_frontend.request_restart_kernel()

    def interrupt_kernel_active_frontend(self):
        self.active_frontend.request_interrupt_kernel()

    def toggle_confirm_restart_active_frontend(self):
        widget = self.active_frontend
        widget.confirm_restart = not widget.confirm_restart
        self.confirm_restart_kernel_action.setChecked(widget.confirm_restart)

    def update_restart_checkbox(self):
        if self.active_frontend is None:
            return
        widget = self.active_frontend
        self.confirm_restart_kernel_action.setChecked(widget.confirm_restart)

    def cut_active_frontend(self):
        widget = self.active_frontend
        if widget.can_cut():
            widget.cut()

    def copy_active_frontend(self):
        widget = self.active_frontend
        widget.copy()

    def copy_raw_active_frontend(self):
        self.active_frontend._copy_raw_action.trigger()

    def paste_active_frontend(self):
        widget = self.active_frontend
        if widget.can_paste():
            widget.paste()

    def undo_active_frontend(self):
        self.active_frontend.undo()

    def redo_active_frontend(self):
        self.active_frontend.redo()

    def reset_magic_active_frontend(self):
        self.active_frontend.execute("%reset")

    def history_magic_active_frontend(self):
        self.active_frontend.execute("%history")

    def save_magic_active_frontend(self):
        self.active_frontend.save_magic()

    def clear_magic_active_frontend(self):
        self.active_frontend.execute("%clear")

    def who_magic_active_frontend(self):
        self.active_frontend.execute("%who")

    def who_ls_magic_active_frontend(self):
        self.active_frontend.execute("%who_ls")

    def whos_magic_active_frontend(self):
        self.active_frontend.execute("%whos")

    def print_action_active_frontend(self):
        self.active_frontend.print_action.trigger()

    def export_action_active_frontend(self):
        self.active_frontend.export_action.trigger()

    def select_all_active_frontend(self):
        self.active_frontend.select_all_action.trigger()

    def increase_font_size_active_frontend(self):
        self.active_frontend.increase_font_size.trigger()

    def decrease_font_size_active_frontend(self):
        self.active_frontend.decrease_font_size.trigger()

    def reset_font_size_active_frontend(self):
        self.active_frontend.reset_font_size.trigger()

    def guiref_active_frontend(self):
        self.active_frontend.execute("%guiref")

    def intro_active_frontend(self):
        self.active_frontend.execute("?")

    def quickref_active_frontend(self):
        self.active_frontend.execute("%quickref")
    #---------------------------------------------------------------------------
    # QWidget interface
    #---------------------------------------------------------------------------

    def closeEvent(self, event):
        """ Forward the close event to every tabs contained by the windows
        """
        if self.tab_widget.count() == 0:
            # no tabs, just close
            event.accept()
            return
        # Do Not loop on the widget count as it change while closing
        title = self.window().windowTitle()
        cancel = QtGui.QMessageBox.Cancel
        okay = QtGui.QMessageBox.Ok

        if self.confirm_exit:
            if self.tab_widget.count() > 1:
                msg = "Close all tabs, stop all kernels, and Quit?"
            else:
                msg = "Close console, stop kernel, and Quit?"
            info = "Kernels not started here (e.g. notebooks) will be left alone."
            closeall = QtGui.QPushButton("&Quit", self)
            closeall.setShortcut('Q')
            box = QtGui.QMessageBox(QtGui.QMessageBox.Question,
                                    title, msg)
            box.setInformativeText(info)
            box.addButton(cancel)
            box.addButton(closeall, QtGui.QMessageBox.YesRole)
            box.setDefaultButton(closeall)
            box.setEscapeButton(cancel)
            pixmap = QtGui.QPixmap(self._app.icon.pixmap(QtCore.QSize(64,64)))
            box.setIconPixmap(pixmap)
            reply = box.exec_()
        else:
            reply = okay

        if reply == cancel:
            event.ignore()
            return
        if reply == okay:
            while self.tab_widget.count() >= 1:
                # prevent further confirmations:
                widget = self.active_frontend
                widget._confirm_exit = False
                self.close_tab(widget)
            event.accept()


"""
Password generation for the IPython notebook.
"""
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
# Stdlib
import getpass
import hashlib
import random

# Our own
from IPython.core.error import UsageError
from IPython.testing.skipdoctest import skip_doctest
from IPython.utils.py3compat import cast_bytes, str_to_bytes

#-----------------------------------------------------------------------------
# Globals
#-----------------------------------------------------------------------------

# Length of the salt in nr of hex chars, which implies salt_len * 4
# bits of randomness.
salt_len = 12

#-----------------------------------------------------------------------------
# Functions
#-----------------------------------------------------------------------------

@skip_doctest
def passwd(passphrase=None, algorithm='sha1'):
    """Generate hashed password and salt for use in notebook configuration.

    In the notebook configuration, set `c.NotebookApp.password` to
    the generated string.

    Parameters
    ----------
    passphrase : str
        Password to hash.  If unspecified, the user is asked to input
        and verify a password.
    algorithm : str
        Hashing algorithm to use (e.g, 'sha1' or any argument supported
        by :func:`hashlib.new`).

    Returns
    -------
    hashed_passphrase : str
        Hashed password, in the format 'hash_algorithm:salt:passphrase_hash'.

    Examples
    --------
    In [1]: passwd('mypassword')
    Out[1]: 'sha1:7cf3:b7d6da294ea9592a9480c8f52e63cd42cfb9dd12'

    """
    if passphrase is None:
        for i in range(3):
            p0 = getpass.getpass('Enter password: ')
            p1 = getpass.getpass('Verify password: ')
            if p0 == p1:
                passphrase = p0
                break
            else:
                print('Passwords do not match.')
        else:
            raise UsageError('No matching passwords found. Giving up.')

    h = hashlib.new(algorithm)
    salt = ('%0' + str(salt_len) + 'x') % random.getrandbits(4 * salt_len)
    h.update(cast_bytes(passphrase, 'utf-8') + str_to_bytes(salt, 'ascii'))

    return ':'.join((algorithm, salt, h.hexdigest()))

def passwd_check(hashed_passphrase, passphrase):
    """Verify that a given passphrase matches its hashed version.

    Parameters
    ----------
    hashed_passphrase : str
        Hashed password, in the format returned by `passwd`.
    passphrase : str
        Passphrase to validate.

    Returns
    -------
    valid : bool
        True if the passphrase matches the hash.

    Examples
    --------
    In [1]: from IPython.lib.security import passwd_check

    In [2]: passwd_check('sha1:0e112c3ddfce:a68df677475c2b47b6e86d0467eec97ac5f4b85a',
       ...:              'mypassword')
    Out[2]: True

    In [3]: passwd_check('sha1:0e112c3ddfce:a68df677475c2b47b6e86d0467eec97ac5f4b85a',
       ...:              'anotherpassword')
    Out[3]: False

    """
    try:
        algorithm, salt, pw_digest = hashed_passphrase.split(':', 2)
    except (ValueError, TypeError):
        return False

    try:
        h = hashlib.new(algorithm)
    except ValueError:
        return False

    if len(pw_digest) == 0:
        return False

    h.update(cast_bytes(passphrase, 'utf-8') + str_to_bytes(salt, 'ascii'))

    return h.hexdigest() == pw_digest