Phone Multi-tap Spelling Inspired by the Google Code Challenge:

The Latin alphabet contains 26 characters and telephones only have ten digits on the keypad. We would like to make it easier to write a message to your friend using a sequence of keypresses to indicate the desired characters. The letters are mapped onto the digits as shown below. To insert the character B for instance, the program would press 22. In order to insert two characters in sequence from the same key, the user must pause before pressing the key a second time. The space character ' ' should be printed to indicate a pause. For example, 2 2 indicates AA whereas 22 indicates B.
Each message will consist of only lowercase characters a-z and space characters ' '. Pressing zero emits a space.


Your challenge is to write the smallest function which takes the input string, and returns the sequence of keypresses necessary to produce the input as string or output it to stdout. The function which is the least amount of bytes wins.
Example Input/Output
phone(&quot;hi&quot;)
44 444
phone(&quot;hello world&quot;)
4433555 555666096667775553

Other clarifications

Pauses must only be added when necessary and must be a space ' '.
Each message will consist of only lowercase characters a-z and space characters ' '. Print 0 to signify spaces.
No external libraries.
Only the input string may be passed to your function.
To make other languages competitive, the primary function declaration doesn't count, and nor does importing other standard libraries. #includes, imports, and usings don't count. Everything else does. This does include #defines and helper functions. See rule 2 in this question if you are confused.
Multiple spaces can be denoted as 00 or 0 0 since you don't really have to pause between a space
Ruby, 129 122 115 111 108 107 105

Done with golfing...

Oops, completely forgot to remove unnecessary spaces - fixed...

Saved 2 chars thanks to Peter Taylor.

Online version

def t9(t)
(t.tr(" ",?`).bytes.map{|c|"09998887777666555444333222"[96-c..-1][/(.)\1*/]}*' ').gsub /(\d) (?!\1)/,'\1'
end


Explanation:

space is translated to the char with the ordinal 96

(t.tr(" ",?`).bytes


characters are first mapped to series of numbers:
- a to 2
- b to 22
- d to 3222
- h to 444333222

a regex expression then matches the first group of equal digits

map{|c|"09998887777666555444333222"[96-c..-1][/(.)\1*/]}


the array is joined

*' ')


all spaces in the occurences of "digit space different_digit" are removed

gsub /(\d) (?!\1)/,'\1'