It's a hack, see fixcoord in pyreadline's console.py (revision 
        1289)
973606
def _get_coord(self, coord):
        
        x, y = coord
        return self.ctypes.c_int(y << 16 | x)
773350
def make_patch( expected, actual )
      diffs = Diff::LCS.sdiff( expected.split("\n"), actual.split("\n"),
        Diff::LCS::ContextDiffCallbacks )

      maxcol = diffs.flatten.
        collect {|d| [d.old_element.to_s.length, d.new_element.to_s.length ] }.
        flatten.max || 0
      maxcol += 4

      patch = "              %#{maxcol}s | %s\n" % [ "Expected", "Actual" ]
      patch << diffs.collect do |changeset|
        changeset.collect do |change|
          "%s [%03d, %03d]: %#{maxcol}s | %-#{maxcol}s" % [
            change.action,
            change.old_position,
            change.new_position,
            change.old_element.inspect,
            change.new_element.inspect,
          ]
        end.join("\n")
      end.join("\n---\n")
    end
1270795
function fixRelativeCssUrls(cssText, baseUrl) {
    const cssUrls = cssText
        // Remove comments
        .replace(regex.cssComments, '')
        // Match url(...) values
        .match(regex.cssUrls) || [];

    cssUrls.forEach(cssUrl => {
        const oldUrl = cssUrl.replace(regex.cssUrls, '$1');
        const newUrl = getFullUrl(oldUrl, baseUrl);

        cssText = cssText.replace(cssUrl, cssUrl.replace(oldUrl, newUrl));
    });

    return cssText;
}
132909
function fixDoubleBlack(stack) {
  var n, p, s, z
  for(var i=stack.length-1; i>=0; --i) {
    n = stack[i]
    if(i === 0) {
      n._color = BLACK
      return
    }
    //console.log("visit node:", n.key, i, stack[i].key, stack[i-1].key)
    p = stack[i-1]
    if(p.left === n) {
      //console.log("left child")
      s = p.right
      if(s.right && s.right._color === RED) {
        //console.log("case 1: right sibling child red")
        s = p.right = cloneNode(s)
        z = s.right = cloneNode(s.right)
        p.right = s.left
        s.left = p
        s.right = z
        s._color = p._color
        n._color = BLACK
        p._color = BLACK
        z._color = BLACK
        recount(p)
        recount(s)
        if(i > 1) {
          var pp = stack[i-2]
          if(pp.left === p) {
            pp.left = s
          } else {
            pp.right = s
          }
        }
        stack[i-1] = s
        return
      } else if(s.left && s.left._color === RED) {
        //console.log("case 1: left sibling child red")
        s = p.right = cloneNode(s)
        z = s.left = cloneNode(s.left)
        p.right = z.left
        s.left = z.right
        z.left = p
        z.right = s
        z._color = p._color
        p._color = BLACK
        s._color = BLACK
        n._color = BLACK
        recount(p)
        recount(s)
        recount(z)
        if(i > 1) {
          var pp = stack[i-2]
          if(pp.left === p) {
            pp.left = z
          } else {
            pp.right = z
          }
        }
        stack[i-1] = z
        return
      }
      if(s._color === BLACK) {
        if(p._color === RED) {
          //console.log("case 2: black sibling, red parent", p.right.value)
          p._color = BLACK
          p.right = repaint(RED, s)
          return
        } else {
          //console.log("case 2: black sibling, black parent", p.right.value)
          p.right = repaint(RED, s)
          continue  
        }
      } else {
        //console.log("case 3: red sibling")
        s = cloneNode(s)
        p.right = s.left
        s.left = p
        s._color = p._color
        p._color = RED
        recount(p)
        recount(s)
        if(i > 1) {
          var pp = stack[i-2]
          if(pp.left === p) {
            pp.left = s
          } else {
            pp.right = s
          }
        }
        stack[i-1] = s
        stack[i] = p
        if(i+1 < stack.length) {
          stack[i+1] = n
        } else {
          stack.push(n)
        }
        i = i+2
      }
    } else {
      //console.log("right child")
      s = p.left
      if(s.left && s.left._color === RED) {
        //console.log("case 1: left sibling child red", p.value, p._color)
        s = p.left = cloneNode(s)
        z = s.left = cloneNode(s.left)
        p.left = s.right
        s.right = p
        s.left = z
        s._color = p._color
        n._color = BLACK
        p._color = BLACK
        z._color = BLACK
        recount(p)
        recount(s)
        if(i > 1) {
          var pp = stack[i-2]
          if(pp.right === p) {
            pp.right = s
          } else {
            pp.left = s
          }
        }
        stack[i-1] = s
        return
      } else if(s.right && s.right._color === RED) {
        //console.log("case 1: right sibling child red")
        s = p.left = cloneNode(s)
        z = s.right = cloneNode(s.right)
        p.left = z.right
        s.right = z.left
        z.right = p
        z.left = s
        z._color = p._color
        p._color = BLACK
        s._color = BLACK
        n._color = BLACK
        recount(p)
        recount(s)
        recount(z)
        if(i > 1) {
          var pp = stack[i-2]
          if(pp.right === p) {
            pp.right = z
          } else {
            pp.left = z
          }
        }
        stack[i-1] = z
        return
      }
      if(s._color === BLACK) {
        if(p._color === RED) {
          //console.log("case 2: black sibling, red parent")
          p._color = BLACK
          p.left = repaint(RED, s)
          return
        } else {
          //console.log("case 2: black sibling, black parent")
          p.left = repaint(RED, s)
          continue  
        }
      } else {
        //console.log("case 3: red sibling")
        s = cloneNode(s)
        p.left = s.right
        s.right = p
        s._color = p._color
        p._color = RED
        recount(p)
        recount(s)
        if(i > 1) {
          var pp = stack[i-2]
          if(pp.right === p) {
            pp.right = s
          } else {
            pp.left = s
          }
        }
        stack[i-1] = s
        stack[i] = p
        if(i+1 < stack.length) {
          stack[i+1] = n
        } else {
          stack.push(n)
        }
        i = i+2
      }
    }
  }
}
866139
function glitch ( params ) {
	params = sanitizeInput( params );

	let inputFn;
	let outputFn;

	const worker = new Worker( URL.createObjectURL(new Blob(["function isImageData ( imageData ) {\n\treturn (\n\t\timageData && \n\t\ttypeof imageData.width === 'number' &&\n\t\ttypeof imageData.height === 'number' &&\n\t\timageData.data &&\n\t\ttypeof imageData.data.length === 'number' &&\n\t\ttypeof imageData.data === 'object'\n\t);\n}\n\nconst base64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\nconst base64Map = base64Chars.split( '' );\nconst reversedBase64Map = { };\n\nbase64Map.forEach( ( val, key ) => { reversedBase64Map[val] = key; } );\n\nvar maps = {\n\tbase64Map,\n\treversedBase64Map\n};\n\nconst reversedBase64Map$1 = maps.reversedBase64Map;\n\n// https://github.com/mutaphysis/smackmyglitchupjs/blob/master/glitch.html\n// base64 is 2^6, byte is 2^8, every 4 base64 values create three bytes\nfunction base64ToByteArray ( base64URL ) {\t\n\tconst result = [ ];\n\tlet prev;\n\n\tconst srcURL = base64URL.replace( 'data:image/jpeg;base64,', '' );\n\n\tfor ( var i = 0, len = srcURL.length; i < len; i++ ) {\n\t\tconst char = srcURL[ i ];\n\t\tconst currentChar = reversedBase64Map$1[ srcURL[ i ] ];\n\t\tconst digitNum = i % 4;\n\n\t\tswitch ( digitNum ) {\n\t\t\t// case 0: first digit - do nothing, not enough info to work with\n\t\t\tcase 1: // second digit\n\t\t\t\tresult.push( prev << 2 | currentChar >> 4 );\n\t\t\t\tbreak;\n\t\t\t\n\t\t\tcase 2: // third digit\n\t\t\t\tresult.push( ( prev & 0x0f ) << 4 | currentChar >> 2 );\n\t\t\t\tbreak;\n\t\t\t\n\t\t\tcase 3: // fourth digit\n\t\t\t\tresult.push( ( prev & 3 ) << 6 | currentChar );\n\t\t\t\tbreak;\n\t\t}\n\n\t\tprev = currentChar;\n\t}\n\n\treturn result;\n}\n\n// http://stackoverflow.com/a/10424014/229189\n\nfunction jpgHeaderLength ( byteArr ) {\n\tlet result = 417;\n\n\t// https://en.wikipedia.org/wiki/JPEG#Syntax_and_structure\n\t// looks for the first occurence of 0xFF, 0xDA in the byteArray\n\t// which is the start of scan\n\tfor ( let i = 0, len = byteArr.length; i < len; i++ ) {\n\t\tif ( byteArr[i] === 0xFF && byteArr[i + 1] === 0xDA ) {\n\t\t\tresult = i + 2;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn result;\n}\n\nfunction glitchByteArray ( byteArray, seed, amount, iterationCount ) {\n\tconst headerLength = jpgHeaderLength( byteArray );\n\tconst maxIndex = byteArray.length - headerLength - 4;\n\n\tconst amountPercent = amount / 100;\n\tconst seedPercent   = seed / 100;\n\n\tfor ( var iterationIndex = 0; iterationIndex < iterationCount; iterationIndex++ ) {\n\t\tconst minPixelIndex = ( maxIndex / iterationCount * iterationIndex ) | 0;\n\t\tconst maxPixelIndex = ( maxIndex / iterationCount * ( iterationIndex + 1 ) ) | 0;\n\t\t\n\t\tconst delta = maxPixelIndex - minPixelIndex;\n\t\tlet pixelIndex = ( minPixelIndex + delta * seedPercent ) | 0;\n\n\t\tif ( pixelIndex > maxIndex ) {\n\t\t\tpixelIndex = maxIndex;\n\t\t}\n\n\t\tconst indexInByteArray = ~~( headerLength + pixelIndex );\n\n\t\tbyteArray[indexInByteArray] = ~~( amountPercent * 256 );\n\t}\n\n\treturn byteArray;\n}\n\nconst base64Map$1 = maps.base64Map;\n\nfunction byteArrayToBase64 ( byteArray ) {\n\tconst result = [ 'data:image/jpeg;base64,' ];\n\tlet byteNum;\n\tlet previousByte;\n\n\tfor ( let i = 0, len = byteArray.length; i < len; i++ ) {\n\t\tconst currentByte = byteArray[i];\n\t\tbyteNum = i % 3;\n\n\t\tswitch ( byteNum ) {\n\t\t\tcase 0: // first byte\n\t\t\t\tresult.push( base64Map$1[ currentByte >> 2 ] );\n\t\t\t\tbreak;\n\t\t\tcase 1: // second byte\n\t\t\t\tresult.push( base64Map$1[( previousByte & 3 ) << 4 | ( currentByte >> 4 )] );\n\t\t\t\tbreak;\n\t\t\tcase 2: // third byte\n\t\t\t\tresult.push( base64Map$1[( previousByte & 0x0f ) << 2 | ( currentByte >> 6 )] );\n\t\t\t\tresult.push( base64Map$1[currentByte & 0x3f] );\n\t\t\t\tbreak;\n\t\t}\n\n\t\tpreviousByte = currentByte;\n\t}\n\n\tif ( byteNum === 0 ) {\n\t\tresult.push( base64Map$1[( previousByte & 3 ) << 4] );\n\t\tresult.push( '==' );\n\t} else {\n\t\tif ( byteNum === 1 ) {\n\t\t\tresult.push( base64Map$1[( previousByte & 0x0f ) << 2] );\n\t\t\tresult.push( '=' );\n\t\t}\n\t}\n\n\treturn result.join( '' );\n}\n\nfunction glitchImageData ( imageData, base64URL, params ) {\n\tif ( isImageData( imageData ) ) {\n\t\tconst byteArray = base64ToByteArray( base64URL );\n\t\tconst glitchedByteArray = glitchByteArray( byteArray, params.seed, params.amount, params.iterations );\n\t\tconst glitchedBase64URL = byteArrayToBase64( glitchedByteArray );\n\t\treturn glitchedBase64URL;\n\t} else {\n\t\tthrow new Error( 'glitchImageData: imageData seems to be corrupt.' );\n\t\treturn;\n\t}\n}\n\nonmessage = msg => {\n\tconst imageData = msg.data.imageData;\n\tconst params = msg.data.params;\n\tconst base64URL = msg.data.base64URL;\n\n\tif ( imageData && base64URL && params ) {\n\t\ttry {\n\t\t\t// phantomjs seems to have some memory loss so we need to make sure\n\t\t\tif ( typeof imageData.width === 'undefined' && typeof msg.data.imageDataWidth === 'number' ) {\n\t\t\t\timageData.width = msg.data.imageDataWidth;\n\t\t\t}\n\n\t\t\tif ( typeof imageData.height === 'undefined' && typeof msg.data.imageDataHeight === 'number' ) {\n\t\t\t\timageData.height = msg.data.imageDataHeight;\n\t\t\t}\n\n\t\t\tconst glitchedBase64URL = glitchImageData( imageData, base64URL, params );\n\t\t\tsuccess( glitchedBase64URL );\n\n\t\t} catch ( err ) {\n\t\t\tfail( err );\n\t\t}\n\n\t} else {\n\t\tif ( msg.data.imageData ) {\n\t\t\tfail( 'Parameters are missing.' );\n\t\t} else {\n\t\t\tfail( 'ImageData is missing.' );\n\t\t}\n\t}\n\t\n\tself.close();\n};\n\nfunction fail ( err ) {\n\tself.postMessage( { err: err.message || err } );\n}\n\nfunction success ( base64URL ) {\n\tself.postMessage( { base64URL: base64URL } );\n}\n"],{type:'text/javascript'})) );
	
	const api = { getParams, getInput, getOutput };
	const inputMethods = { fromImageData, fromImage };
	const outputMethods = { toImage, toDataURL, toImageData };

	function getParams () {
		return params;
	}

	function getInput () {
		const result = objectAssign( { }, api );

		if ( ! inputFn ) {
			objectAssign( result, inputMethods );
		}

		return result;
	}

	function getOutput () {
		const result = objectAssign( { }, api );

		if ( ! outputFn ) {
			objectAssign( result, outputMethods );
		}

		return result;
	}

	function noTransform ( x ) { return x; }

	function fromImage ( inputOptions ) { return setInput( imageToImageData, inputOptions ); }
	function fromImageData ( inputOptions ) { return setInput( noTransform, inputOptions ); }

	function toDataURL ( outputOptions ) { return setOutput( noTransform ); }
	function toImage ( outputOptions ) { return setOutput( base64URLToImage, outputOptions, true ); }
	function toImageData ( outputOptions ) { return setOutput( base64URLToImageData, outputOptions, true ); }

	function setInput ( fn, inputOptions, canResolve ) {		
		inputFn = () => {
			return new Promise( ( resolve, reject ) => {
				if ( canResolve ) {
					fn( inputOptions, resolve, reject );
				} else {
					if ( fn === noTransform ) {
						resolve( inputOptions );
					} else {
						try {
							resolve( fn( inputOptions, resolve, reject ) );
						} catch ( err ) {
							reject( err );
						}
					}
				}
			} );
		};

		if ( isReady() ) {
			return getResult();
		} else {
			return getOutput();
		}
	}

	function setOutput ( fn, outputOptions, canResolve ) {
		outputFn = base64URL => {
			return new Promise( ( resolve, reject ) => {
				if ( canResolve ) {
					fn( base64URL, outputOptions, resolve, reject );
				} else {
					if ( fn === noTransform ) {
						resolve( base64URL );
					} else {
						fn( base64URL, outputOptions )
							.then( resolve, reject );
					}
				}
			} );
		};

		if ( isReady() ) {
			return getResult();
		} else {
			return getInput();
		}
	}

	function isReady () {
		return inputFn && outputFn;
	}

	function getResult () {
		return new Promise( ( resolve, reject ) => {
			inputFn()
				.then( imageData => {
					return glitch( imageData, params );
				}, reject )
				.then( base64URL => {
					outputFn( base64URL )
						.then( resolve, reject );
				}, reject );
		} );
	}

	function glitch ( imageData, params ) {
		return new Promise( ( resolve, reject ) => {
			imageDataToBase64( imageData, params.quality )
				.then( base64URL => {
					return glitchInWorker( imageData, base64URL, params );
				}, reject )
				.then( resolve, reject );
		} );
	}

	function glitchInWorker ( imageData, base64URL, params ) {
		return new Promise( ( resolve, reject ) => {
			worker.addEventListener( 'message', event => {
				if ( event.data && event.data.base64URL ) {
					resolve( event.data.base64URL );
				} else {
					if ( event.data && event.data.err ) {
						reject( event.data.err );
					} else {
						reject( event );
					}
				}
			} );

			worker.postMessage( {
				params: params,
				base64URL: base64URL,
				imageData: imageData,

				// phantomjs tends to forget about those two
				// so we send them separately
				imageDataWidth: imageData.width,
				imageDataHeight: imageData.height
			} );
		} );
	}

	return getInput();
}
945919
def _fix_unsafe(shell_input):
    
    _unsafe = re.compile(r'[^\w@%+=:,./-]', 256)
    try:
        if len(_unsafe.findall(shell_input)) == 0:
            return shell_input.strip()
        else:
            clean = "'" + shell_input.replace("'", "'\"'\"'") + "'"
            return clean
    except TypeError:
        return None
726909
private void fixN0c(BracketData bd, int openingIndex, int newPropPosition, byte newProp) {
        /* This function calls itself recursively */
        IsoRun pLastIsoRun = bd.isoRuns[bd.isoRunLast];
        Opening qOpening;
        int k, openingPosition, closingPosition;
        for (k = openingIndex+1; k < pLastIsoRun.limit; k++) {
            qOpening = bd.openings[k];
            if (qOpening.match >= 0)    /* not an N0c match */
                continue;
            if (newPropPosition < qOpening.contextPos)
                break;
            if (newPropPosition >= qOpening.position)
                continue;
            if (newProp == qOpening.contextDir)
                break;
            openingPosition = qOpening.position;
            dirProps[openingPosition] = newProp;
            closingPosition = -(qOpening.match);
            dirProps[closingPosition] = newProp;
            qOpening.match = 0;                                 /* prevent further changes */
            fixN0c(bd, k, openingPosition, newProp);
            fixN0c(bd, k, closingPosition, newProp);
        }
    }
1244951
def fix_cdata(body)
      # <![CDATA[ = &lt;![CDATA[
      # ]]> =  ]]&gt;
      if !body.nil? && body.include?('&lt;![CDATA[')
        body.gsub! '&lt;![CDATA[', '<![CDATA['
        body.gsub! ']]&gt', ']]>'
      end
      body
    end
310731
function patch(obj, method, optionsArgIndex) {
    var orig = obj[method];
    if (!orig) return;
    obj[method] = function () {
      var opts = arguments[optionsArgIndex];
      var file = null;
      if (opts) {
        file = typeof opts == 'string' ? opts : opts.filename;
      }
      if (file) callback(file);
      return orig.apply(this, arguments);
    };
  }
747691
function addCode(script, match, filePath) {
  var leftDeli = match[1], code = match[2];
  if(leftDeli==='<@' || leftDeli==='<!--@='){
    script.push('__p(escape(' + code + '));');
  }
  else if(leftDeli==='<@|' || leftDeli==='<!--@|'){//no escape
    script.push('__p(' + code + ');');
  }
  else{//<!--@ -->
    script.push(code);

    //possible single-line comment check
    var lastLine = code.split('\n').slice(-1)[0];
    if(lastLine.indexOf('//')>=0){
      /*eslint-disable no-console*/
      if(!filePath) console.warn('detect a possible single-line comment: %s', lastLine);
      else console.warn('detect a possible single-line comment in file %s: %s', filePath, lastLine);
      /*eslint-enable no-console*/
    }
    if(code.slice(-1)!==';') script.push(';');
  }
}
872485
private String fixApiDocRoot(String str) {
	if (str == null)
	    return null;
	String fixed = str.trim();
	if (fixed.isEmpty())
	    return "";
	if (File.separatorChar != '/')
	    fixed = fixed.replace(File.separatorChar, '/');
	if (!fixed.endsWith("/"))
	    fixed = fixed + "/";
	return fixed;
    }
796642
function(opt) {
        console.log("\n\n############ENGINE CONFIGURATION OPTIONS############\n");
        console.dir(opt);
        console.log("\n####################################################\n");
        if (!opt.hasOwnProperty('engine')) throw ("Please specify a scheduler engine");
        if (opt.engine === "sge")
            engine = sgeLib;
        else if (opt.engine === "slurm")
            engine = slurmLib;
        else if (opt.engine === "emulator") {
            engine = emulatorLib;
            emulator = true;
        }
        if (opt.engine != "emulator") {
            if (!opt.hasOwnProperty('binaries')) throw "You must specify scheduler engine binaries";
        }
        engine.configure(opt.binaries, jobsArray);
        console.log("Engine configured is " + engine.type());
    }
25128
def _init_ugly_crap():
    
    import ctypes
    from types import TracebackType

    # figure out side of _Py_ssize_t
    if hasattr(ctypes.pythonapi, 'Py_InitModule4_64'):
        _Py_ssize_t = ctypes.c_int64
    else:
        _Py_ssize_t = ctypes.c_int

    # regular python
    class _PyObject(ctypes.Structure):
        pass
    _PyObject._fields_ = [
        ('ob_refcnt', _Py_ssize_t),
        ('ob_type', ctypes.POINTER(_PyObject))
    ]

    # python with trace
    if object.__basicsize__ != ctypes.sizeof(_PyObject):
        class _PyObject(ctypes.Structure):
            pass
        _PyObject._fields_ = [
            ('_ob_next', ctypes.POINTER(_PyObject)),
            ('_ob_prev', ctypes.POINTER(_PyObject)),
            ('ob_refcnt', _Py_ssize_t),
            ('ob_type', ctypes.POINTER(_PyObject))
        ]

    class _Traceback(_PyObject):
        pass
    _Traceback._fields_ = [
        ('tb_next', ctypes.POINTER(_Traceback)),
        ('tb_frame', ctypes.POINTER(_PyObject)),
        ('tb_lasti', ctypes.c_int),
        ('tb_lineno', ctypes.c_int)
    ]

    def tb_set_next(tb, next):
        """Set the tb_next attribute of a traceback object."""
        if not (isinstance(tb, TracebackType) and
                (next is None or isinstance(next, TracebackType))):
            raise TypeError('tb_set_next arguments must be traceback objects')
        obj = _Traceback.from_address(id(tb))
        if tb.tb_next is not None:
            old = _Traceback.from_address(id(tb.tb_next))
            old.ob_refcnt -= 1
        if next is None:
            obj.tb_next = ctypes.POINTER(_Traceback)()
        else:
            next = _Traceback.from_address(id(next))
            next.ob_refcnt += 1
            obj.tb_next = ctypes.pointer(next)

    return tb_set_next
367627
def _patched_method(self, method, *args, **kwargs):
        
        self._validate()
        result = method(*args, **kwargs)
        self._validate()
        return result
126467
function patchHooks(hooks) {
  var original = {};
  var restore;

  hookTypes.map(function(key) {
    original[key] = global[key];

    global[key] = function(title, fn) {
      // Hooks accept an optional title, though they're
      // ignored here for simplicity
      if (!fn) fn = title;
      hooks[key] = createWrapper(fn);
    };
  });

  restore = function() {
    hookTypes.forEach(function(key) {
      global[key] = original[key];
    });
  };

  return restore;
}
272142
function patchMakeErrFromCode() {
  const func = errors.makeErrFromCode;
  function makeErrFromCodeHook() {
    const err = func.apply(null, arguments);
    patchErrorBody(err, {});
    return err;
  }
  errors.makeErrFromCode = makeErrFromCodeHook;

  // Deprecated.
  // See https://github.com/restify/errors/blob/master/lib/index.js#L126
  errors.codeToHttpError = makeErrFromCodeHook;
}
1134837
def patch_spyder3(verbose=False):
    ''' '''
    try:
        # patch spyder/config/utils.py for file extension
        from spyder.config import utils
        src_file = utils.__file__
        spyder_dir = os.path.dirname(os.path.dirname(src_file))
        patch_file(src_file,
        '''
    (_("Cython/Pyrex files"), ('.pyx', '.pxd', '.pxi')),
    (_("C files"), ('.c', '.h')),''',
        '''
    (_("Cython/Pyrex files"), ('.pyx', '.pxd', '.pxi')),
    (_("SoS files"), ('.sos', )),
    (_("C files"), ('.c', '.h')),''',
            verbose=verbose)
        #
        # patch spyder/app/cli_options.py to add command line option --kernel
        patch_file(os.path.join(spyder_dir, 'app', 'cli_options.py'),
            '''help="String to show in the main window title")
    options, args = parser.parse_args()''',
            '''help="String to show in the main window title")
    parser.add_option('--kernel', help="Jupyter kernel to start.")
    options, args = parser.parse_args()''',
            verbose=verbose)
        #
        # patch spyder/utils/sourcecode.py,
        patch_file(os.path.join(spyder_dir, 'utils', 'sourcecode.py'),
                "'Python': ('py', 'pyw', 'python', 'ipy')",
                "'Python': ('py', 'pyw', 'python', 'ipy', 'sos')",
            verbose=verbose)
        patch_file(os.path.join(spyder_dir, 'utils', 'sourcecode.py'),
                '''CELL_LANGUAGES = {'Python': ('#%%', '# %%', '# <codecell>', '# In[')}''',
                '''CELL_LANGUAGES = {'Python': ('#%%', '# %%', '# <codecell>', '# In[', '%cell')}''',
            verbose=verbose)
        #
        # patch spyder/app/mainwindow.py
        patch_file(os.path.join(spyder_dir, 'app', 'mainwindow.py'),
            '''
    app.exec_()
''',
            r'''
    try:
        if options.kernel == 'sos':
            cfg_file = os.path.expanduser('~/.ipython/profile_default/ipython_config.py')
            has_cfg = os.path.isfile(cfg_file)
            if has_cfg and not os.path.isfile(cfg_file + '.sos_bak'):
                os.rename(cfg_file, cfg_file + '.sos_bak')
            with open(cfg_file, 'w') as cfg:
                cfg.write("c.IPKernelApp.kernel_class =  'sos_notebook.spyder_kernel.SoS_SpyderKernel'\n")
        app.exec_()
    finally:
        if options.kernel == 'sos':
            os.remove(cfg_file)
            if os.path.isfile(cfg_file + '.sos_bak'):
                os.rename(cfg_file + '.sos_bak', cfg_file)
''',
            verbose=verbose)
        #
        print('\nSpyder is successfully patched to accept .sos format and sos kernel.')
        print('Use ')
        print()
        print('    $ spyder --kernel sos')
        print()
        print('to start spyder with sos kernel')
    except Exception as e:
        sys.exit('Failed to patch spyder: {}'.format(e))