- correct some misconceptions in how the new lineno thing was built;
record all linenos fully and track printed line numbers accurately
wrt buffered lines and such.
diff --git a/mako/codegen.py b/mako/codegen.py
index 679acf8..46dcc07 100644
--- a/mako/codegen.py
+++ b/mako/codegen.py
@@ -149,13 +149,13 @@
             self.write_metadata_struct()
 
     def write_metadata_struct(self):
-        self.printer.source_map[self.printer.lineno] = self.printer.last_source_line
+        self.printer.source_map[self.printer.lineno] = \
+                    max(self.printer.source_map)
         struct = {
             "filename": self.compiler.filename,
             "uri": self.compiler.uri,
             "source_encoding": self.compiler.source_encoding,
             "line_map": self.printer.source_map,
-            "boilerplate_lines": self.printer.boilerplate_map
         }
         self.printer.writelines(
             '"""',
diff --git a/mako/pygen.py b/mako/pygen.py
index 0ee19f0..3e43c07 100644
--- a/mako/pygen.py
+++ b/mako/pygen.py
@@ -37,31 +37,16 @@
 
         self._reset_multi_line_flags()
 
-        # marker for template source lines; this
-        # is part of source/template line mapping
-        self.last_source_line = 0
-
-        self.last_boilerplate_line = 0
-
         # mapping of generated python lines to template
         # source lines
         self.source_map = {}
 
-        # list of "boilerplate" lines, these are lines
-        # that precede/follow a set of template source-mapped lines
-        self.boilerplate_map = []
-
-
     def _update_lineno(self, num):
-        if self.last_boilerplate_line <= self.last_source_line:
-            self.boilerplate_map.append(self.lineno)
-            self.last_boilerplate_line = self.lineno
         self.lineno += num
 
     def start_source(self, lineno):
-        if self.last_source_line != lineno:
+        if self.lineno not in self.source_map:
             self.source_map[self.lineno] = lineno
-            self.last_source_line = lineno
 
     def write_blanks(self, num):
         self.stream.write("\n" * num)
@@ -75,6 +60,7 @@
         self.in_indent_lines = False
         for l in re.split(r'\r?\n', block):
             self.line_buffer.append(l)
+            self._update_lineno(1)
 
     def writelines(self, *lines):
         """print a series of lines of python."""
@@ -124,7 +110,7 @@
 
         # write the line
         self.stream.write(self._indent_line(line) + "\n")
-        self._update_lineno(1)
+        self._update_lineno(len(line.split("\n")))
 
         # see if this line should increase the indentation level.
         # note that a line can both decrase (before printing) and
@@ -244,13 +230,11 @@
         for entry in self.line_buffer:
             if self._in_multi_line(entry):
                 self.stream.write(entry + "\n")
-                self._update_lineno(1)
             else:
                 entry = entry.expandtabs()
                 if stripspace is None and re.search(r"^[ \t]*[^# \t]", entry):
                     stripspace = re.match(r"^([ \t]*)", entry).group(1)
                 self.stream.write(self._indent_line(entry, stripspace) + "\n")
-                self._update_lineno(1)
 
         self.line_buffer = []
         self._reset_multi_line_flags()
diff --git a/test/test_template.py b/test/test_template.py
index 3dd42be..c4ab99a 100644
--- a/test/test_template.py
+++ b/test/test_template.py
@@ -1251,15 +1251,44 @@
         eq_(
             ModuleInfo.get_module_source_metadata(t.code, full_line_map=True),
             {
+                'full_line_map': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+                                    0, 0, 0, 0, 0, 0, 1, 4, 5, 5, 5, 7, 8,
+                                    8, 8, 8, 8, 8, 8],
                 'source_encoding': 'ascii',
-                'uri': '/some/template',
                 'filename': None,
-                'boilerplate_lines': [1, 21],
-                'full_line_map': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-                                1, 1, 1, 1, 1, 1, 1, 4, 5, 5, 5, 7, 8, 8,
-                                8, 8, 8, 8, 8],
-                'line_map': {34: 8, 21: 1, 22: 4, 23: 5, 26: 7, 27: 8}
+                'line_map': {34: 28, 14: 0, 21: 1, 22: 4, 23: 5, 24: 5,
+                                    25: 5, 26: 7, 27: 8, 28: 8},
+                'uri': '/some/template'
             }
+
+        )
+
+    def test_metadata_two(self):
+        t = Template("""
+Text
+Text
+% if bar:
+    ${expression}
+% endif
+
+    <%block name="foo">
+        hi block
+    </%block>
+
+
+""", uri="/some/template")
+        eq_(
+            ModuleInfo.get_module_source_metadata(t.code, full_line_map=True),
+            {
+                'full_line_map': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+                            0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 5, 5, 5, 7, 7, 7,
+                            7, 7, 10, 10, 10, 10, 10, 10, 8, 8, 8, 8, 8,
+                            8, 8, 8, 8, 8, 8, 8],
+                'source_encoding': 'ascii',
+                'filename': None,
+                'line_map': {33: 10, 39: 8, 45: 8, 14: 0, 51: 45, 23: 1,
+                                24: 4, 25: 5, 26: 5, 27: 5, 28: 7},
+                'uri': '/some/template'}
         )
 
 class PreprocessTest(TemplateTest):