diff --git a/scapy/asn1packet.py b/scapy/asn1packet.py
index dc900b0a2f99ca7a3d51c1ae3010bbc2d163b52b..e49942ce9d9cbedd9fee7472c2fc0056fc24faf9 100644
--- a/scapy/asn1packet.py
+++ b/scapy/asn1packet.py
@@ -12,7 +12,7 @@ class ASN1_Packet(Packet):
         flist = self.ASN1_root.get_fields_list()
         self.do_init_fields(flist)
         self.fields_desc = flist    
-    def do_build(self):
+    def self_build(self):
         return self.ASN1_root.build(self)    
     def do_dissect(self, x):
         return self.ASN1_root.dissect(self, x)
diff --git a/scapy/packet.py b/scapy/packet.py
index 1f51f3181109c046f84d0df4c34a66d92c63afba..3410a925b029182371719f563f89829423a3bcba 100644
--- a/scapy/packet.py
+++ b/scapy/packet.py
@@ -281,37 +281,44 @@ class Packet(BasePacket):
         return True
     def __len__(self):
         return len(self.__str__())
-    def do_build(self):
+    def self_build(self, field_pos_list=None):
         p=""
         for f in self.fields_desc:
             val = self.getfieldval(f.name)
             if isinstance(val, RawVal):
-                p += str(val)
+                sval = str(val)
+                p += sval
+                if field_pos_list is not None:
+                    field_pos_list.append( (f.name, sval.encode("string_escape"), len(p), len(sval) ) )
             else:
                 p = f.addfield(self, p, val)
         return p
-    
-    def post_build(self, pkt, pay):
-        """DEV: called right after the current layer is build."""
-        return pkt+pay
 
-    def build_payload(self):
-        return self.payload.build(internal=1)
+    def do_build_payload(self):
+        return self.payload.do_build()
 
-    def build(self,internal=0):
+    def do_build(self):
         if not self.explicit:
             self = self.__iter__().next()
-        pkt = self.do_build()
+        pkt = self.self_build()
         for t in self.post_transforms:
             pkt = t(pkt)
-        pay = self.build_payload()
+        pay = self.do_build_payload()
         p = self.post_build(pkt,pay)
-        if not internal:
-            pad = self.payload.getlayer(Padding) 
-            if pad: 
-                p += pad.build()
-            p = self.build_done(p)
         return p
+    
+    def build_padding(self):
+        return self.payload.build_padding()
+
+    def build(self):
+        p = self.do_build()
+        p += self.build_padding()
+        p = self.build_done(p)
+        return p
+    
+    def post_build(self, pkt, pay):
+        """DEV: called right after the current layer is build."""
+        return pkt+pay
 
     def build_done(self, p):
         return self.payload.build_done(p)
@@ -1029,8 +1036,12 @@ class NoPayload(Packet):
         return ""
     def __nonzero__(self):
         return False
-    def build(self, internal=0):
-        return ""    
+    def do_build(self):
+        return ""
+    def build(self):
+        return ""
+    def build_padding(self):
+        return ""
     def build_done(self, p):
         return p
     def build_ps(self, internal=0):
@@ -1109,11 +1120,10 @@ class Raw(Packet):
         
 class Padding(Raw):
     name = "Padding"
-    def build(self, internal=0):
-        if internal:
-            return ""
-        else:
-            return Raw.build(self)
+    def self_build(self):
+        return ""
+    def build_padding(self):
+        return self.load+self.payload.build_padding()
 
 conf.raw_layer = Raw
 if conf.default_l2 is None:
diff --git a/test/regression.uts b/test/regression.uts
index f5b5f732c653cc38a5a8ec8d98223c8a435efd68..069c617ddb4520d604289e7e1527f80cb0d75e18 100644
--- a/test/regression.uts
+++ b/test/regression.uts
@@ -125,7 +125,7 @@ assert( _ == "abcdef" )
 str(Raw("ABC")/Padding("abc")/Padding("def"))
 assert( _ == "ABCabcdef" )
 str(Raw("ABC")/Padding("abc")/Raw("DEF")/Padding("def"))
-assert( _ == "ABCabcDEFdef" )
+assert( _ == "ABCDEFabcdef" )
 
 = Padding and length computation
 IP(str(IP()/Padding("abc")))