The biggest programming mistakes I've had the displeasure of making, or discovering in others code, almost always centre around one of these two problems:
1. The code is over-engineered
2. The code was abstracted before there was even a need for the abstraction.
I remember when I was less experienced, how thrilled I'd be over code that was clever, solved many problems aside from the one I was trying to solve, and had some clear reusability built in. What a work of art, I thought.... until I eventually realised that much of the extra code I had written didn't get used, the abstracted code was never reused - or even if it was, I couldn't predict how it would be reused and the abstraction was clumsy at best, useless at worst.
It's sad when this happens - good intentions, but the end result is a lot of waste. I'm embarrassed to look over my earlier code which is like this.. I like to think I do it less now, but the temptation is always there... I'm going to need to do this later anyway... I can just abstract this bit here and reuse it some day in the future...
My advice now... Don't do it! Just wait until the reuse case comes along, or the new feature request comes along, and *then* do it. You'll know so much more about the problem domain then, or you might avoid days (weeks!) of wasted effort.