The solution should be modular and organized, as large and unwieldy solutions are often hard to maintain and update. You should consider breaking up the code into small chunks of discrete processing and functionality. Smaller units are easier to understand and maintain. However, if the units are too small, you can end up with too many of them. On the other hand, if they are too large, the code can become monolithic and unmanageable.
Furthermore, things are going to change. Wherever possible you should think about the implementation and try to avoid tight coupling. You can use interfaces and delegates to promote extensibility. Functionality changes should be relatively straightforward to implement; they shouldn't require major re-factoring.
Under normal circumstances, the project criteria will determine how much flexibility and extensibility you can include within the foundation architecture. However, you should certainly "lay the foundation" for future expansion and enhancement, taking it into account during planning, designing, and estimating. The best way to allow for future growth and support change is to store as much information in "configuration" as possible. Configuration values are much easier to change than source code. However, changes need to be managed appropriately.
Consider the following groups of configuration settings:
Application-specific configuration settings — This group encompasses the application-specific configuration settings ...