Determine Semantics and Structure
... returnValue functionName(Parameter1, Parameter2)
Detailed statement of step one in processing this function.
call unfinishedFunction(): retrieve CustomObjectKey (_)
Detailed statement of step two in processing this function.
Detailed statement of part one of step two in processing this function
create Class1.unfinishedObject: retrieve CustomObject (_)
Detailed statement of part two of step two in processing this function
call Class2.finishedFunction(Parameter1): retrieve outputXhtml (X)
Output the return value, if it exists.
This is another step that I carry out a little more formally than traditional PPP; the emphasis is on giving some consideration to semantics. I'm also clearly addressing some issues of class structure as well. In fact, when I put together a detailed pseudocode design, I group related functions by their class name. Sometimes your comment will translate directly into code, then nothing more is required. However, especially in the higher-level abstractions, there is too much code to write. These comments won't translate into code you can implement, so you will have to delegate the responsibility to another function.
As you can see, when I need to call another function, I create a second line of pseudocode. At first, the function name and the abstraction returned is all the information I write down. I also create the function call as a link to the appropriate function – though the link won't go anywhere until I write the pseudocode for the function it links to. This is the key; as the other functions are added, the links let you easily walk the pathways of the application to get a feel for the design and how it will actually work. This is how I will read the application typically, though I can also read it top down to review each class in turn. Finally, I include "(_)" to clearly indicate on a visual inspection that I still need to write the function I'm calling. When the function is completed I change this to (X). Now, by doing a simple search in my code editor for (_), I can find the next function to create for the design.
Step one demonstrates a function call to a function that's in the same class. However, there will be times that I instantiate another object in my function and call it's members. In step 2 - part 1, I demonstrate this using a class (Class1) to create a new object. This not only demands that we consider the name of the function and the name of the class, but which class each function is going to live in. Considering the ramifications of these details and working them out as early as possible, will make it that much more likely that our design will be strong and easy to construct.
In step 2 - part 2, I've finished the function so I've crossed it off "(X)" as a visual indication that it's done. I have included the parameters in the finished function, though finalizing parameters is one of the last things that typically come together for me. However, this phase is where I'm playing with different signatures for the function and determining if I'll need to overload the function and how.
Once I've included the parameters, any change to the function signature probably requires me to change all the links as well. If I have defined my helper functions well, this could be a huge job so I like to be reasonably sure I won't have to do that much; including the parameters is something I hold off doing until late in the design (at least for the links). This may be a reason that McConnell does not implement PPP this way. However, including the parameters in each function call lets you move back and forth between the call and the function to ensure that you didn't change one, and forget to update the other. Given the nasty surprises that common mistake can cause during construction, I find the advantages significantly outweigh the drawbacks.
Repetition
One thing you'll notice is that the work in this phase keeps bringing up phrases like "I don't know at first" and "I'm not ready until..." Determining the I / O and constructing the procedure is really about getting the pseudocode of each function written up the first time through. Once that's done, we start looking over the design again and again and again. Once you've got all the pseudocode written, you have the tool you've wanted to maximize your ability to review the high level abstractions and logic in your application repeatedly. Each time through, you can focus on particular details to the exclusion of all others. Do all my classes conform well to their abstractions? Review the design to see. Is there any repetitive code in the application that I could break out into utility functions? Review the design to see, etc.
Steve McConnell even recommends repeating the entire PPP process a few times. That takes a lot of discipline, but I have seen the process produce important results; at the very least, I'd recommend running it a second time, without referring to your first pseudocode design. Even if you sit down with the purpose of replicating it from memory, in any non-trivial application you'll be shocked how different your second attempt turns out to be. Ideally you will really sit down from scratch and write out the application pseudocode as seems best to you for the second time. Each divergence from the first pseudocode design gives you a good point where you can consider your options and determine which way to go.
While repeating the entire PPP process is a major undertaking, I've seen it actually save time. In any design, developers stress about particular decisions and waste a lot of time trying to decide what to do, whether they're in design or construction or wherever they find it. Repeating PPP can solve some of these intractable problems really easily; as you go through and write the pseudocode several times, there's no reason to question a choice if you keep making the design the same way. No matter how "close" a decision seems in your head, if you keep making it the same way in the end, it's really not close at all. This is another place where formal PPP tells you a lot more about an application design and saves you a lot of time compared to less formal methodologies.