def writeUidlResponce(self, callback, repaintAll, outWriter, window,
                analyzeLayouts):

        outWriter.write('\"changes\":[')

        paintables = None

        invalidComponentRelativeSizes = None

        paintTarget = JsonPaintTarget(self, outWriter, not repaintAll)
        windowCache = self._currentlyOpenWindowsInClient.get(window.getName())
        if windowCache is None:
            windowCache = OpenWindowCache()
            self._currentlyOpenWindowsInClient[window.getName()] = windowCache

        # Paints components
        if repaintAll:
            paintables = list()
            paintables.append(window)

            # Reset sent locales
            self._locales = None
            self.requireLocale( self._application.getLocale() )
        else:
            # remove detached components from paintableIdMap so they
            # can be GC'ed
            # TODO figure out if we could move this beyond the painting phase,
            # "respond as fast as possible, then do the cleanup". Beware of
            # painting the dirty detatched components.
            for p in self._paintableIdMap.keys():
                if p.getApplication() is None:
                    self.unregisterPaintable(p)
                    if self._paintableIdMap[p] in self._idPaintableMap:
                        del self._idPaintableMap[self._paintableIdMap[p]]
                    if p in self._paintableIdMap:
                        del self._paintableIdMap[p]
                    if p in self._dirtyPaintables:
                        self._dirtyPaintables.remove(p)

            paintables = self.getDirtyVisibleComponents(window)

        if paintables is not None:
            # We need to avoid painting children before parent.
            # This is ensured by ordering list by depth in component
            # tree

            def compare(c1, c2):
                d1 = 0
                while c1.getParent() is not None:
                    d1 += 1
                    c1 = c1.getParent()
                d2 = 0
                while c2.getParent() is not None:
                    d2 += 1
                    c2 = c2.getParent()
                if d1 < d2:
                    return -1
                if d1 > d2:
                    return 1
                return 0

            paintables.sort(cmp=compare)

            for p in paintables:
                # TODO CLEAN
                if isinstance(p, Window):
                    w = p
                    if w.getTerminal() is None:
                        w.setTerminal(
                            self._application.getMainWindow().getTerminal())

                # This does not seem to happen in tk5, but remember this case:
                # else if (p instanceof IComponent) { if (((IComponent)
                # p).getParent() == null || ((IComponent) p).getApplication() ==
                # null) { // IComponent requested repaint, but is no // longer
                # attached: skip paintablePainted(p); continue; } }

                # TODO we may still get changes that have been
                # rendered already (changes with only cached flag)
                if paintTarget.needsToBePainted(p):
                    paintTarget.startTag('change')
                    paintTarget.addAttribute('format', 'uidl')
                    pid = self.getPaintableId(p)
                    paintTarget.addAttribute('pid', pid)

                    p.paint(paintTarget)

                    paintTarget.endTag('change')

                self.paintablePainted(p)

                if analyzeLayouts:

                    # FIXME: circular import
                    from muntjac.terminal.gwt.server.component_size_validator \
                        import ComponentSizeValidator

                    w = p
                    invalidComponentRelativeSizes = ComponentSizeValidator.\
                            validateComponentRelativeSizes(w.getContent(),
                                    None, None)

                    # Also check any existing subwindows
                    if w.getChildWindows() is not None:
                        for subWindow in w.getChildWindows():
                            invalidComponentRelativeSizes = \
                                    ComponentSizeValidator.\
                                    validateComponentRelativeSizes(
                                            subWindow.getContent(),
                                            invalidComponentRelativeSizes,
                                            None)

        paintTarget.close()
        outWriter.write(']')  # close changes

        outWriter.write(', \"meta\" : {')
        metaOpen = False

        if repaintAll:
            metaOpen = True
            outWriter.write('\"repaintAll\":true')
            if analyzeLayouts:
                outWriter.write(', \"invalidLayouts\":')
                outWriter.write('[')
                if invalidComponentRelativeSizes is not None:
                    first = True
                    for invalidLayout in invalidComponentRelativeSizes:
                        if not first:
                            outWriter.write(',')
                        else:
                            first = False
                        invalidLayout.reportErrors(outWriter, self, stderr)
                outWriter.write(']')

            if self._highLightedPaintable is not None:
                outWriter.write(", \"hl\":\"")
                idd = self._paintableIdMap.get(self._highLightedPaintable)
                outWriter.write(idd if idd is not None else 'null')
                outWriter.write("\"")
                self._highLightedPaintable = None

        ci = None
        try:
            ci = self._application.getSystemMessages()
        except __HOLE__, e:
            logger.warning('getSystemMessages() failed - continuing')

        # meta instruction for client to enable auto-forward to
        # sessionExpiredURL after timer expires.
        if ((ci is not None) and (ci.getSessionExpiredMessage() is None)
                and (ci.getSessionExpiredCaption() is None)
                and ci.isSessionExpiredNotificationEnabled()):
            newTimeoutInterval = self.getTimeoutInterval()
            if repaintAll or (self._timeoutInterval != newTimeoutInterval):
                if ci.getSessionExpiredURL() is None:
                    escapedURL = ''
                else:
                    escapedURL = ci.getSessionExpiredURL().replace('/', '\\/')
                if metaOpen:
                    outWriter.write(',')

                outWriter.write('\"timedRedirect\":{\"interval\":'
                        + newTimeoutInterval + 15 + ',\"url\":\"'
                        + escapedURL + '\"}')
                metaOpen = True

            self._timeoutInterval = newTimeoutInterval

        outWriter.write('}, \"resources\" : {')

        # Precache custom layouts

        # TODO We should only precache the layouts that are not
        # cached already (plagiate from usedPaintableTypes)
        resourceIndex = 0
        for resource in paintTarget.getUsedResources():
            is_ = None
            try:
                is_ = callback.getThemeResourceAsStream(self.getTheme(window),
                        resource)
            except IOError, e:
                # FIXME: Handle exception
                logger.info('Failed to get theme resource stream.')

            if is_ is not None:
                outWriter.write((', ' if resourceIndex > 0 else '')
                        + '\"' + resource + '\" : ')
                resourceIndex += 1  # post increment
                layout = str()
                try:
                    layout = is_.read()
                except IOError, e:
                    # FIXME: Handle exception
                    logger.info('Resource transfer failed: ' + str(e))

                outWriter.write('\"%s\"' % JsonPaintTarget.escapeJSON(layout))
            else:
                # FIXME: Handle exception
                logger.critical('CustomLayout not found: ' + resource)

        outWriter.write('}')

        usedPaintableTypes = paintTarget.getUsedPaintableTypes()
        typeMappingsOpen = False
        for class1 in usedPaintableTypes:
            if windowCache.cache(class1):
                # client does not know the mapping key for this type,
                # send mapping to client
                if not typeMappingsOpen:
                    typeMappingsOpen = True
                    outWriter.write(', \"typeMappings\" : { ')
                else:
                    outWriter.write(' , ')
                canonicalName = clsname(class1)

                if canonicalName.startswith('muntjac.ui'):
                    # use Muntjac package names  FIXME: Python client side
                    canonicalName = 'com.vaadin.ui.' + class1.__name__
                elif canonicalName.startswith('muntjac.demo.sampler'):
                    canonicalName = 'com.vaadin.demo.sampler.' + class1.__name__
                elif hasattr(class1, 'TYPE_MAPPING'):
                    canonicalName = getattr(class1, 'TYPE_MAPPING')
                else:
                    raise ValueError('type mapping name [%s]' % canonicalName)

                outWriter.write('\"')
                outWriter.write(canonicalName)
                outWriter.write('\" : ')
                outWriter.write(self.getTagForType(class1))

        if typeMappingsOpen:
            outWriter.write(' }')

        # add any pending locale definitions requested by the client
        self.printLocaleDeclarations(outWriter)

        if self._dragAndDropService is not None:
            self._dragAndDropService.printJSONResponse(outWriter)
dataset/ETHPy150Open rwl/muntjac/muntjac/terminal/gwt/server/abstract_communication_manager.py/AbstractCommunicationManager.writeUidlResponce