Here are two of denis's rules of programming (learned the hard way).

Rule #1: It is good to avoid working on complex solutions for problems that might not exist.

Rule #2: It is good to postpone implementing solutions until you really understand the problems.

It follows from these rules that:
  1. One should avoid creating reusable code (solution) which will not necessarily find much use (problem).
  2. One should generally avoid writing reusable code (solution) until such time as one understands the problem inside out (has solved the problem the tedious way many times).
If you do not adhere to these rules, you will create more solutions than there are problems to solve, and the solutions you create will not be entirely appropriate to the problems that actually exist. Thus, the solutions themselves become part of the problem.

General-purpose solutions are hard to do right, and one shouldn't generally start implementing such solutions just because there might be a problem. You only start implementing them once you know the problem is there, and you've already had to solve it in a specific case several times, so that you have a good idea of what writing the general-purpose solution will entail.