def write(self, filename=None):
        """Write the PE file.
        
        This function will process all headers and components
        of the PE file and include all changes made (by just
        assigning to attributes in the PE objects) and write
        the changes back to a file whose name is provided as
        an argument. The filename is optional, if not 
        provided the data will be returned as a 'str' object.
        """
        
        file_data = list(self.__data__)
        for structure in self.__structures__:
            
            struct_data = list(structure.__pack__())
            offset = structure.get_file_offset()
            
            file_data[offset:offset+len(struct_data)] = struct_data
        
        if hasattr(self, 'VS_VERSIONINFO'):
            if hasattr(self, 'FileInfo'):
                for entry in self.FileInfo:
                    if hasattr(entry, 'StringTable'):
                        for st_entry in entry.StringTable:
                            for key, entry in st_entry.entries.items():
                                
                                offsets = st_entry.entries_offsets[key]
                                lengths = st_entry.entries_lengths[key]
                                
                                if len( entry ) > lengths[1]:
                                    
                                    l = list()
                                    for idx, c in enumerate(entry):
                                        if ord(c) > 256:
                                            l.extend( [ chr(ord(c) & 0xff), chr( (ord(c) & 0xff00) >>8) ]  )
                                        else:
                                            l.extend( [chr( ord(c) ), '\0'] )
                                    
                                    file_data[
                                        offsets[1] : offsets[1] + lengths[1]*2 ] = l
                                
                                else:
                                    
                                    l = list()
                                    for idx, c in enumerate(entry):
                                        if ord(c) > 256:
                                            l.extend( [ chr(ord(c) & 0xff), chr( (ord(c) & 0xff00) >>8) ]  )
                                        else:
                                            l.extend( [chr( ord(c) ), '\0'] )

                                    file_data[
                                        offsets[1] : offsets[1] + len(entry)*2 ] = l
                                    
                                    remainder = lengths[1] - len(entry)
                                    file_data[
                                        offsets[1] + len(entry)*2 :
                                        offsets[1] + lengths[1]*2 ] = [
                                            u'\0' ] * remainder*2
                
        new_file_data = ''.join( [ chr(ord(c)) for c in file_data] )
        
        if filename:
            f = file(filename, 'wb+')
            f.write(new_file_data)
            f.close()
        else:
            return new_file_data