When you close a bug, there should be a reason for closing the bug. The most obvious, of course, is fixed, but could not reproduce, not a bug and won't fix are equally valid.
Could Not Reproduce means exactly that - the person assigned to fix the bug has followed the step to reproduce the bug (your bug report does include those, right?) but cannot get the bug to occur on their development system. This status doesn't mean that the bug doesn't exist, merely that there are additional steps or conditions for the bug to occur; I have, for example, had bugs that occurred only under very specific temperature conditions. If this bug is important - see below - then it needs to go back to the testers to isolate the true conditions.
Not a Bug means that the behavior is not a bug, but that it is working as designed. You'll often see this when testing games - the tester believes something different should happen, but that is not what is in the design document. The tester might well be right, but testing is generally the wrong time for major design changes.
Will Not Fix is similar, but rather than working as design, it's a minor problem that won't greatly affect most users.
Keep in mind that not all bugs are created equal. Those which crash on start-up on every platform have the highest priority, while those which cause an insignificant graphical glitch under unusual circumstances would get a much lower priority. Programmers need to concentrate on fixing bugs based on their priority; as time goes by and the dreaded ship-date approaches, entire categories of bugs will be placed into the will not fix state. These bugs might be fixed in a later patch, but not right now.
So who assigns priority? Initially, the testers will, using some form of checklist or rubric. Next, the QA lead & programming lead should discuss new bugs before finalizing the categorization and assigning them to programmers to fix. The priority isn't fixed; additional testing might indicate the bugs are more or less serious, or occur more or less frequently. And, of course, as the delivery date approaches, some bugs seem far less important...
Once a bug has been resolved by the programmer, it still isn't closed. If it's been marked as fixed, then it has to go back to QA to verify that it has been fixed. Could not reproduce can either go back for more testing or left to sit if it's unimportant. Not a bug will typically need some confirmation that it's working as designed, while will not fix generally needs some sign off from upper management.