public function stringReplace($string, $replace)
    {
        if ($this->_mappingsChanged) {
            $this->_generateMappings();
        }

        if (strpos("\n", $string)) {
            throw new Exception('string must not contain \n');
        }
        if ($replace != "" && strpos("\n", $replace)) {
            throw new Exception('replace must not contain \n');
        }

        $adjustOffsets = array();
        $pos = 0;
        $str = $this->_fileContents;
        $offset = 0;
        $lineOffset = 0;
        while (($pos = strpos($str, $string, $pos)) !== false) {
            $line = substr_count(substr($str, 0, $pos), "\n") + 1;
            if (!isset($adjustOffsets[$line])) {
                //first in line
                $lineOffset = 0;
            }
            $this->_fileContents = substr($this->_fileContents, 0, $pos + $offset).$replace.substr($this->_fileContents, $pos + $offset + strlen($string));
            $offset += strlen($replace) - strlen($string);
            $lineOffset += strlen($replace) - strlen($string);
            $column = $pos - strrpos(substr($str, 0, $pos), "\n") + 1; //strrpos can return false for first line which will subtract 0 (=false)
            $adjustOffsets[$line][] = array(
                'column' => $column,
                'absoluteOffset' => $offset,
                'lineOffset' => $lineOffset,
                'offset' => strlen($replace) - strlen($string),
                'replacedLength' => strlen($string)
            );
            $pos = $pos + strlen($string);
        }

        $mappings = $this->getMappings();
        $this->_mappingsChanged = true;
        $this->_mappings = array();
        foreach ($mappings as $mappingIndex=>$mapping) {
            if (isset($adjustOffsets[$mapping['generatedLine']])) {
                foreach (array_reverse($adjustOffsets[$mapping['generatedLine']], true) as $offsIndex=>$offs) {
                    if ($mapping['generatedColumn'] > $offs['column']) {
                        if ($mapping['generatedColumn'] < $offs['column']-1+$offs['replacedLength']) {
                            //mapping inside replaced test, remove
                            continue 2;
                        } else {
                            $mapping['generatedColumn'] += $offs['lineOffset'];
                            break;
                        }
                    }
                }
            }
            $this->_mappings[] = $mapping;
        }
    }