Evolving legacy software with a generic program transformation framework using meta-programming and domain-specific languages