Code generation patterns

The subject disclosure pertains to code generation patterns for use in object relational mapping. The code patterns may be used to manage bidirectional relationships and ensure consistency. The code patterns may support on-demand or deferred loading of relational data. Change detection and tracking are also provided. In addition, a default member modifier allows developers to override tool generated source code without directly modifying the generated source code.

CROSS-REFERENCE TO RELATED APPLICATIONS

This application is related to co-pending U.S. application Ser. No. 11/193,574, entitled, “RETRIEVING AND PERSISTING OBJECTS FROM/TO RELATIONAL DATABASES”, filed on Jul. 29, 2005, and co-pending U.S. patent application Ser. No. 11/193,573, entitled, “INTELLIGENT SQL GENERATION FOR PERSISTENT OBJECT RETRIEVAL”, filed on Jul. 29, 2005. The entireties of the aforementioned applications are incorporated herein by reference.

BACKGROUND

Due to continuous increases in memory and processing power, code generation has become popular method of increasing programmer productivity. In recent years, the popularity of code generators has increased. Code generators automatically generate source-level language code (e.g., C, C#, Visual Basic, Java . . . ). Use of automatically generated code may reduce development time and increase stability of code.

In particular, code generation has become popular in the context of object-relational mapping (ORM). Relational data storage systems (e.g., DB2, SQL Server, MySQL, . . . ) are utilized to store relational data and manage these of relationships. It is useful for software developed in source-level languages to access and manipulate the relational data stored in the relational data storage system. When the application software is managing the relational data, it should maintain the relationships inherent in the data. In addition, any changes or modifications to the relational data should be persisted back to the relational data storage system.

SUMMARY

Briefly described, the provided subject matter concerns machine-generated source. More specifically, the subject matter concerns machine generated source code related to the mapping of relational data to an object model while managing the data relationships. Code generation patterns are described which provide bidirectional relationships between data objects.

The generated object model may support on-demand or deferred loading of relational data from a data storage system. The object model may utilize a generic type to create a set of data tables corresponding the data storage system data tables. This allows the data storage system to be represented as a class containing data tables for each data storage system data table mapped to the object model.

The object model may also be capable of detecting and tracking changes to data pulled from the data storage system. The system provides an efficient method of identifying update data and preventing overwriting of modified data storage system data.

In addition, a default member modifier is provided. The default modifier provides developers the ability to override tool-generated source code with out directly modifying the source code.

DETAILED DESCRIPTION

The word “exemplary” is used herein to mean serving as an example, instance, or illustration. Any aspect or design described herein as “exemplary” is not necessarily to be construed as preferred or advantageous over other aspects or designs. In addition, while the examples provided utilize the C# programming language, numerous alternative programming languages may be used.

I. Default Member Modifier

Referring now toFIG. 1, in general, programmers use code generating tools or source code generators to produce an initial structure for a program and then modify the generated source code. However, if it is necessary to generate the code again during software development, the developer's changes to the generated code will be overwritten. Consequently, developers may create separate source code files. Certain source level languages facilitate modification of generated code using separate source files. For example, C# provides partial types that allow classes and interfaces to be separated into multiple pieces and separate source files. A tool generated partial class can be merged with a developer written partial class during compilation, so that each partial class can be independently created and maintained.FIG. 1illustrates a compilation system. During compilation the developer source code102and the generated source code104are combined by the compiler component106. The resulting implementation code108(e.g., executable, intermediate language . . . ) is the same as if the developer source code102and the generated source code104had been written in a single unit.

Partial classes provide software developers with the ability to add members to partial classes declared in tool generated source code, but do not allow developers to modify members declared in the generated source code. A member of a partial class may be declared either in generated code or in developer code, but not in both. If a member is declared more than once for a partial class, the compiler will generate a conflict.

The code generator may provide a default class member modifier. The default member modifier indicates that the member declaration is to be used in the absence of a nondefault member declaration. Consequently, the default member may be overwritten by a nondefault class member. This provides software developers with a mechanism to modify tool-generated members of partial classes without generating a conflict during compilation.

FIG. 2is a flowchart illustrating a method200for processing of default members. Beginning at reference number202, a compiler receives source code. The source code may be produced by a code generation tool, a software developer or both. At204, a default member modifier is detected. When the compiler finds a default member in a partial class, the compiler component determines whether there is an identically named member of the class that overrides the default member at206. The overriding member may be in a separate developer created source file. If there is a nondefault or overriding member, at208the compiler will utilize the source code of the overriding member and disregard the default source code. At212, the implementation code is generated using the overriding source code. However, in the absence of any overriding code, at210the default source code is utilized and the implementation code incorporates the default source code at212. The compilation process terminates at214.

Consider the following C# class declaration in generated source code file Customer1.cs:

partial class Customer {public string Status {get{return status;}set{status = value;if (status == “Gold”) PremierList.Add(this);}}public decimal ComputeDiscount( ){// Custom computation different from the code above}. . .}
Here, the developer has not defined a Name member. Therefore, the default Name member defined in the generated code will be utilized by the compiler. The developer has defined a property member Status and a method member ComputeDiscount. The two members are identical in name to the members of partial class Customer declared in the generated source code, but include different or additional logic. Because of the member modifier default, the members declared in the software developer's source code would take precedence over the generated code property and method. The default member modifier allows developers to override class members in the generated code without directly modifying the generated source code files.

The default member modifier may also be utilized with blueprints. As used herein, a blueprint is a declarative language document (e.g., extended markup language (XML)) that may be translated into source code. All partial class members generated using blueprints may automatically be specified with the default modifier unless the default modifier is explicitly turned off. Consider the following exemplary blueprint:

<class name=“Northwind.Customer” table=“Customers”><property name=“Name” column=“ContactName”defaultModifier=“False”/>. . .</class>
The default modifier may be turned off explicitly, if desired, by specifying an attribute, such as the defaultModifier for the Customer Name property. Alternatively, partial class members generated using blueprints may automatically be specified not to use default, unless the default modifier is explicitly turned on.
II. Code Generation Patterns For Relationship Management

Referring now toFIG. 3, tool generated code is frequently used in ORM systems. As shown inFIG. 3, an ORM system300may include an ORM component302that acts as an interface between an application component304and a data storage component306. Relational data may be retrieved from the data storage component306and managed by the ORM component302for use by the application component304.

Conventional ORM systems fail to adequately provide for relationship management. In general, there are three problematic relationship types: one-to-one, one-to-many and many-to-many. In a one-to-one relationship each entity of type A has a relationship with exactly one entity of type B and the entity of type B has a corresponding relationship with the entity of type A. For example, in a simple inventory system each customer A has a unique credit card number and each credit card number has exactly one customer associated with it. In a one-to-many relationship a single entity of type A has a relationship with one or more entities of type B, but each entity of type B is associated with a single entity of type A. For example, in the inventory system a customer may place one or more orders and each order will be associated with the single customer who placed the order. Finally, in a many-to-many relationship an entity of type A may have a relationship with more than one entity of type B, and each entity of type B may have a relationship with more than one entity of type A. For example, an order may be placed for a number of products and a single product may be included in multiple orders.

In general, object-oriented languages do not provide software developers with tools to manage relational data and ensure consistency of relationships. For example, when data for a one-to-many relationship such as the customer order relationship is mapped using object oriented source code, it is frequently mapped as illustrated in the following C# class declarations:

class Customer{. . .public List<Order> Orders;}class Order{. . .public Customer Customer;}
Here, the source code includes by declaring an Order class with a Customer member and a Customer class and having a member, Orders, where Orders is a list of orders associated an instance of Customer. While the instances of the Customer and Order classes illustrated above may be populated with relational data, the classes fail to require consistency in the relationships between the objects. There is no mechanism to prevent a developer's code from modifying orders for a Customer instance without updating the Customer member for the corresponding order. When objects are populated with relational data, it is the responsibility of the programmer to ensure that the objects are consistent with the relational data. Similarly, when an object such as an order is removed, the programmer is responsible for ensuring that all the relevant relationships are updated. If an Order is deleted, the Order must be removed from the list of orders for the related Customer.

An ORM system may use the code generation patterns described below to model one-to-one, one-to-many and many-to-many relationships while enforcing relationship consistency. The code generation patterns may include a container component, also referred to as a container that provides for the enforcement of the bidirectional relationships required to adequately model relational data. Each data object component, also referred to as a data object, (e.g., Customer) may include a container that includes information corresponding to other data objects in the relationship (e.g., Order). The data objects and containers may be used in pairs to model the one-to-one, one-to-many and many-to-many relationships. Each container may include one or more notifications that allow the container to notify corresponding data object if the relationship between the data objects is modified.

Containers may be implemented as generic classes that can be instantiated for different types of objects. A container may include an aggregate of a set of data objects (e.g., a set of orders). Containers that include a set of data objects are referred to as set containers. Alternatively, the container may include a reference to a data object (e.g., customer name for an order), rather than a set of data objects. Such containers are referred to herein as reference containers. A pair of reference containers may be used to model a one-to-one relationship. A pair of set containers may be used to model a many-to-many relationship. The combination of a reference container and a set container may be used to model the one-to-many relationship.

FIG. 4is a block diagram of illustrating the customer order relationship. A customer data object402has a set container404that includes object information corresponding to the order data object406. Similarly, the order data object406has a reference container408that includes object information corresponding to the customer data object402. The set container may include a notification component (not shown), such that a change to the object information contained in set container404causes a notification to be sent to the order data object406. Similarly, the reference container may include a notification component (not shown), such that a change to the object information contained in reference container408causes a notification to be sent to the customer data object402. Consider the following C# code:

partial class Customer{. . .public EntitySet<Order> Orders;}partial class Order{. . .public EntityRef<Customer> Customer;}
Here, the list of orders associated with a customer is implemented as a set container using the EntitySet class and the customer associated with an order is implemented as a reference container using the EntityRef class. The EntitySet class and EntityRef class are described in detail below.

Consider an exemplary implementation of EntitySet:

EntitySet may be used to implement a set container for a customer's collection of orders. EntityRef may be used to implement a reference container used to store the customer associated with each order. Containers implemented using EntitySet and EntityRef may be paired to manage the one-to-many customer order relationship. EntityRef will be discussed in further detail below. Consider now an exemplary implementation of the Customer class for the customer order relationship discussed above utilizing the relationship management of EntitySet:

public partial class Customer : IChangeNotifier {. . .private EntitySet<Order> _Orders;public Customer( ) {/* the following code provides the delegates forOrder object to be used for Add( ) and Remove( ) operations */this._Orders = new EntitySet<Order>(newSystem.Query.Notification<Order>(this.attach_Orders), newSystem.Query.Notification<Order>(this.detach_Orders));}. . .private void attach_Orders(Order entity) {this.OnChanging( );entity.Customer = this;}private void detach_Orders(Order entity) {this.OnChanging( );entity.Customer = null;}}
Here, the container infrastructure implemented by EntitySet may be used to add an Order to a Customer data object's collection of Orders. Only the parts of the generated code relevant to addition and deletion of Orders are shown above while the rest of the code is elided.

Class Customer includes an EntitySet container having a collection of order data objects. The Customer class includes methods attach_Orders and detach_Orders, which update the Customer member of an associated Order entity. Delegates for these methods are passed as parameters to the EntitySet constructor. Therefore, the Add and Remove methods of the EntitySet class, defined above, will use these methods for onAdd and onRemove.

FIG. 5is a flow chart diagram of a programming methodology500for adding a data object to a container for a one-to-many relationship while maintaining data object relationships. In particular, we will discuss addition of an order in the context of the customer order example discussed above. At reference numeral502, the addition process is begun. A call may be made to add a data object to a collection of data objects. For example, an Order, Ord1, may be added to an instance of a customer, Cust1 by the call “Cust1.Orders.Add(Ord1).” At504, basic error checking may be performed to determine whether the data object to be added is null. If there is an error, an exception may be generated at506. Otherwise, at508the data object may be added to the collection of data objects. After the data object is added, there is a notification of the addition at510and the data object is updated to reflect the relationship at512. Specifically, Ord1.Customer is set to Cust1. The process terminates at514.

FIG. 6is a flow chart diagram of a programming methodology600for removing a data object from a set container for a one-to-many relationship while maintaining data object relationships. In particular, we will discuss removal of an order within the context of the customer order example discussed above. At reference numeral602, the removal process is begun. A call may be made to remove a data object from a collection of data objects. For example, an Order, Ord2, may be removed from an instance of a customer, Cust1, by the call “Cust1.Orders.Remove(Ord2).” At604, basic error checking may be performed to determine whether the data object to be removed is null. If there is an error, an exception may be generated at606. Otherwise, at608the data object may be removed from the collection of data objects. After the data object is removed, there is a notification of the removal at610and the data object is updated to reflect the relationship at612. Specifically, Ord2.Customer is set to null. The process terminates at614.

A reference container may contain a reference to a data object rather than a collection of data objects. The reference container may be thought of as a more limited form of the set container and includes the same notifications present in the set container. The reference container may be used when mapping a one-to-one or a one-to-many relationship. For example, a reference container, implemented below as EntityRef, may be used with a set container implemented using EntitySet to model the customer order relationship discussed above. Consider the following exemplary implementation of EntityRef in C#:

FIG. 7is a flow chart diagram of a programming methodology700for removing a data object from a set container while maintaining data object relationships. In particular, we will discuss addition or removal of an order with respect to our customer order example. At reference numeral702, a call is made to update a data object. For example, an Order, Ord1, may be updated to add a customer, Cust1, by the call “Order =Cust1.” At704, a determination is made whether to add or remove the data object. If an order is to be removed, notification to remove the data object from the collection of data objects at706and the value is set to null at708. The process then terminates at710. However, if the order is to be added, the value is set at712and notification to add the data object to the collection of data objects at714. The process terminates at710.

Using set containers and reference containers, one can model one-to-one, one-to-many and many-to-many relationships. However, in order to prevent looping of notifications, a protocol must be established in which one member of the pair of containers retains control and manages the relationship. Looping would occur if the notification from the first container in the pair of containers triggered a notification from the second container back to the first container.

The source code for reference containers may be optimized. The reference container may be thought of as a limited set container. The functionality of the reference container may be achieved without declaring a separate class (e.g., EntityRef). As shown in the following C# code, the functionality of the reference container may be moved inside the declaration of partial class (e.g., Order) to reduce overhead.

public partial class Order {private EntityRef<Customer> _Customer;public Customer Customer {get {return this._Customer.Entity;}set {Customer v = this._Customer.Entity;if ((v != value)) {if ((v != null)) {this._Customer.Entity = null;v.Orders.Remove(this);}this._Customer.Entity = value;if ((value != null)) {value.Orders.Add(this);}}}}}
Here, the Customer property for the class Order includes a set accessor that adds or removes the order form the customer's list of orders. The set accessor is the functional equivalent of the onAdd and onRemove methods of the EntityRef class described above.

Optimizing the reference container may reduce overhead during processing, but may result in less concise source code. However, source code conciseness or clarity may not be critical for tool generated source code.

III. Deferred or Delayed Loading

The object relational mapping infrastructure may also provide for deferred or delayed loading of relational data. In general, relational data is retrieved from a data storage component either in a batch at the beginning of processing or on an as needed basis. For data intensive programming batch retrieval of data may require large amounts of memory to store the data during processing. Deferring the loading of data until the data is referenced reduces the amount of memory required. However, data objects should be loaded into memory prior to being referenced.

FIG. 8is a flowchart illustrating a method800for performing on demand of deferred loading in an ORM system. Beginning at reference numeral802, during processing a call is made to navigate to a data object. Navigation to the data object is intercepted at804. At806, a determination is made as to whether the data object is already populated and contains the relational data or whether the data object has not yet been populated. If the data object contains the relational data, navigation to the data object continues at812. Otherwise, the relational data corresponding to the data object is retrieved from a data storage component at808. Retrieval may include a database query or any other method of data retrieval. At810, the data object is populated using the retrieved data. Navigation to the data object continues at812.

The reference and set containers may include a loading component to provide for deferred loading of relational data. The containers may intercept navigation between data objects, query the data storage component, and create and populate data objects on the fly, thereby creating the illusion that the data objects are fully populated without actually requiring loading every data object into memory prior to use.

The following exemplary C# code provides additional members to the EntitySet class to provide for delayed or deferred loading:

Typically, data objects are stored in relational data tables for data storage systems or components such as databases. For example, in the inventory system discussed above, the data storage component may include a table of customers and a table of orders. When a new customer or order is added to the inventory system, a row is added to the appropriate table. Similarly, when a customer or order is deleted from the inventory system, a row is deleted from the appropriate table.

When modeling relational data from a data storage system using an object-oriented programming construct, the object model or construct should include a set of strongly typed data object tables corresponding to the relational data tables of the data storage system. The programming language construct data object tables may be a representation of the relational data tables of the data storage system for use in the application. In the inventory system example, the generated source code should include a table of Customers and a table of Orders.

Any changes to the construct tables by the application should be tracked and persisted to the data storage system tables. For example, each newly created instance of classes such as Customer should be tracked so that the corresponding data storage system table may be updated by inserting a new corresponding Customer row into the table. Similarly, deletions of Customers or other class instances should be tracked and persisted to the corresponding data storage system table for deletion of the rows.

Data object tables may be created using a generic class (e.g., Table). The generic class may be specialized to handle the different types of objects (e.g., customers, orders, suppliers, shippers . . . ) stored in the data object tables. Using a generic class to implement the data object tables leverages the common features of the tables. For example, each table may require a method to add and remove data objects. Consider the following exemplary declaration of Table:

public class Table<T> {public void Add(T item) {// Object relational mapping infrastructure tracks the item to be added}public void Remove(T item) {// Object relational mapping infrastructure tracks the item to beremoved}}
Defining members Add and Remove in the generic class Table eliminates the necessity of creating an Add and Remove member for each individual data object table.

FIG. 9illustrates a method900for creating a set of data object tables corresponding to data storage system tables. Beginning at reference number902, the number of tables and type of each table in the data storage system are determined. At904, a data object table corresponding to a data storage system table is instantiated using a generic class. At906, a check is made to determine whether there are additional data storage system tables to model. If yes, the next data object table is instantiated at904. If all of the data storage system tables have been modeled, the method terminates at908.

For the example inventory system, a data context may be created using a set of data object tables to mirror the data storage system tables. Consider the following C# code:

public partial class Northwind : DataContext {public Table<Category> Categories;public Table<Customer> Customers;public Table<Shipper> Shippers;public Table<Supplier> Suppliers;public Table<Order> Orders;public Table<Product> Products;}
Here, the generic class Table is used to create a collection of Customers, Shippers, Suppliers, Orders and Products. As used herein, Table<T> is a virtual representation of the corresponding data storage system table. The generated code provides for strong type checking for the Add and Remove methods for the individual data object tables. Generating the data object tables also spares the software developer from having to define a separate table class for each table of the data storage system, reducing work and debugging time for the developer.

Only the newly created instances and retrieved instances that are deleted are tracked using the strongly typed tables. An exemplary method for calling the generated code to ensure that new and deleted instances are appropriately tracked is shown:

The code generation system may also provide for detection and tracking of changes to relational data pulled from data storage systems into object models. When relational data is pulled from a data storage system to populate data objects used by an application, the data objects may be modified without knowledge of the ORM system. However, any insertions, modifications or deletions should be persisted back to the data storage system. In addition, while a first application is processing, other applications may access the data storage system and modify the relational data that was used to populate the data objects used by the first application. When relational data is persisted to the data storage system from the first application, it should not overwrite changes made by other applications.

One simple solution is to maintain a copy of all data objects; the copies containing the original data retrieved from the data storage system. The copies may be compared with the current value of the data objects to determine if the data object has been modified. This results in memory being used to store identical copies for data objects that remain unchanged. In addition, when the modifications are persisted to the data storage system, each data object is compared to its copy containing the original values to determine if there has been any change to the data object. Processing time is wasted comparing data objects that have remained unchanged.

In one aspect of the disclosed subject matter, the code generator component may generate source level code, visible and modifiable by a developer, to implement change detection and tracking. The change detection and tracking may be implemented in source level code rather than hidden in an intermediate format (e.g., bytecode or IL (intermediate language)). Placing the implementation in source level code makes it transparent to software developers.

The generated code may create copies only for those data objects that are modified by the application. This would eliminate the need to create copies of each data object and minimize the space overhead by limiting the number of copies. In addition, this would eliminate the processing time required to compare unchanged data objects to their copies to determine if the data objects have changed.

Turning now toFIG. 10, the container source code may include a change notification component that notifies a change detection component in the ORM system when a data object is about to be modified. The change notification component may utilize an event handler.FIG. 10illustrates a method1000for tracking modified objects. Beginning at reference numeral1002, an application makes a call to update a data object. At1004, a notification is triggered by the call to update the data object. At1006, the change detection component checks if the data object has been previously copied. If the data object has not been copied before, the change detection component copies the data object and adds the copy of the data object to a list of modified data objects at1008. If the data object has already been copied, a copy of the original data object has already been added to the list and should not be overwritten. At1010, the data object is updated as specified by the application. Consider the following exemplary C# code:

public partial class Customer : IChangeNotifier {private string_CustomerID;public string CustomerID {get {return this._CustomerID;}set {if ((this._CustomerID != value)) {// The following notification causes a copy of the originalvaluesthis.OnChanging();this._CustomerID = value;}}}private void OnChanging() {if ((this.ObjectChanging != null)) {this.ObjectChanging(this, System.EventArgs.Empty);}}}A notification interface may be used to specify an event handler forthe changing object:public interface IChangeNotifier {event ObjectChangingEventHandler ObjectChanging;}
Here, the set accessor for a property within the Customer class, described in detail above, includes a notification that tells the change detection component of the ORM system that the data object is about to change. The ORM system is notified just before the data object is actually changed to allow the ORM system to create a copy before the data object is modified.

Turning now toFIG. 11, at some point the modifications to the data objects should be persisted back to the data storage system.FIG. 11illustrates a method1100for persisting changes to the data storage system. Beginning at1102, the first data object copy is retrieved from the list of modified data objects. The data object copies contain the original relational data pulled from the data storage system. At1104, the data object copy is compared to the data object in the data storage system. At1106, a check is made to determine whether the data object copy is different from the data storage system object. if yes, then the data object in the data storage system has been modified and an exception may be generated at1108. If the data object copy and the data storage system object are identical, then the data storage system object was unchanged and at1110the modified data object may be persisted to the data storage system. At1112a check is made to determine whether there are additional data objects in the list of modified data objects. If yes, the next data object copy is retrieved at1102. Otherwise, the method terminates at1114.

The aforementioned systems have been described with respect to interaction between several components. It should be appreciated that such systems and components can include those components or sub-components specified therein, some of the specified components or sub-components, and/or additional components. Sub-components could also be implemented as components communicatively coupled to other components rather than included within parent components. Additionally, it should be noted that one or more components may be combined into a single component providing aggregate functionality or divided into several sub-components. The components may also interact with one or more other components not specifically described herein but known by those of skill in the art.

Furthermore, as will be appreciated various portions of the disclosed systems above and methods below may include or consist of artificial intelligence or knowledge or rule based components, sub-components, processes, means, methodologies, or mechanisms (e.g., support vector machines, neural networks, expert systems, Bayesian belief networks, fuzzy logic, data fusion engines, classifiers . . . ). Such components, inter alia, can automate certain mechanisms or processes performed thereby to make portions of the systems and methods more adaptive as well as efficient and intelligent.

Additionally, it should be further appreciated that the methodologies disclosed hereinafter and throughout this specification are capable of being stored on an article of manufacture to facilitate transporting and transferring such methodologies to computers. The term article of manufacture, as used, is intended to encompass a computer program accessible from any computer-readable device, carrier, or media.

In order to provide a context for the various aspects of the disclosed subject matter,FIGS. 12 and 13as well as the following discussion are intended to provide a brief, general description of a suitable environment in which the various aspects of the disclosed subject matter may be implemented. While the subject matter has been described above in the general context of computer-executable instructions of a computer program that runs on a computer and/or computers, those skilled in the art will recognize that the invention also may be implemented in combination with other program modules. Generally, program modules include routines, programs, components, data structures, etc. that perform particular tasks and/or implement particular abstract data types. Moreover, those skilled in the art will appreciate that the inventive methods may be practiced with other computer system configurations, including single-processor or multiprocessor computer systems, mini-computing devices, mainframe computers, as well as personal computers, hand-held computing devices (e.g., personal digital assistant (PDA), phone, watch . . . ), microprocessor-based or programmable consumer or industrial electronics, and the like. The illustrated aspects may also be practiced in distributed computing environments where tasks are performed by remote processing devices that are linked through a communications network. However, some, if not all aspects of the invention can be practiced on stand-alone computers. In a distributed computing environment, program modules may be located in both local and remote memory storage devices.

With reference toFIG. 12, an exemplary environment1210for implementing various aspects disclosed herein includes a computer1212(e.g., desktop, laptop, server, hand held, programmable consumer or industrial electronics . . . ). The computer1212includes a processing unit1214, a system memory1216, and a system bus1218. The system bus1218couples system components including, but not limited to, the system memory1216to the processing unit1214. The processing unit1214can be any of various available microprocessors. Dual microprocessors and other multiprocessor architectures also can be employed as the processing unit1214.

The system memory1216includes volatile memory1220and nonvolatile memory1222. The basic input/output system (BIOS), containing the basic routines to transfer information between elements within the computer1212, such as during start-up, is stored in nonvolatile memory1222. By way of illustration, and not limitation, nonvolatile memory1222can include read only memory (ROM), programmable ROM (PROM), electrically programmable ROM (EPROM), electrically erasable ROM (EEPROM), or flash memory. Volatile memory1220includes random access memory (RAM), which acts as external cache memory. By way of illustration and not limitation, RAM is available in many forms such as synchronous RAM (SRAM), dynamic RAM (DRAM), synchronous DRAM (SDRAM), double data rate SDRAM (DDR SDRAM), enhanced SDRAM (ESDRAM), Synchlink DRAM (SLDRAM), and direct Rambus RAM (DRRAM).

It is to be appreciated thatFIG. 12describes software that acts as an intermediary between users and the basic computer resources described in suitable operating environment1210. Such software includes an operating system1228. Operating system1228, which can be stored on disk storage1224, acts to control and allocate resources of the computer system1212. System applications1230take advantage of the management of resources by operating system1228through program modules1232and program data1234stored either in system memory1216or on disk storage1224. It is to be appreciated that the present invention can be implemented with various operating systems or combinations of operating systems.

A user enters commands or information into the computer1212through input device(s)1236. Input devices1236include, but are not limited to, a pointing device such as a mouse, trackball, stylus, touch pad, keyboard, microphone, joystick, game pad, satellite dish, scanner, TV tuner card, digital camera, digital video camera, web camera, and the like. These and other input devices connect to the processing unit1214through the system bus1218via interface port(s)1238. Interface port(s)1238include, for example, a serial port, a parallel port, a game port, and a universal serial bus (USB). Output device(s)1240use some of the same type of ports as input device(s)1236. Thus, for example, a USB port may be used to provide input to computer1212and to output information from computer1212to an output device1240. Output adapter1242is provided to illustrate that there are some output devices1240like displays (e.g., flat panel and CRT), speakers, and printers, among other output devices1240that require special adapters. The output adapters1242include, by way of illustration and not limitation, video and sound cards that provide a means of connection between the output device1240and the system bus1218. It should be noted that other devices and/or systems of devices provide both input and output capabilities such as remote computer(s)1244.

Computer1212can operate in a networked environment using logical connections to one or more remote computers, such as remote computer(s)1244. The remote computer(s)1244can be a personal computer, a server, a router, a network PC, a workstation, a microprocessor based appliance, a peer device or other common network node and the like, and typically includes many or all of the elements described relative to computer1212. For purposes of brevity, only a memory storage device1246is illustrated with remote computer(s)1244. Remote computer(s)1244is logically connected to computer1212through a network interface1248and then physically connected via communication connection(s)1250. Network interface1248encompasses communication networks such as local-area networks (LAN) and wide-area networks (WAN). LAN technologies include Fiber Distributed Data Interface (FDDI), Copper Distributed Data Interface (CDDI), Ethernet/IEEE 802.3, Token Ring/IEEE 802.5 and the like. WAN technologies include, but are not limited to, point-to-point links, circuit-switching networks like Integrated Services Digital Networks (ISDN) and variations thereon, packet switching networks, and Digital Subscriber Lines (DSL).

Communication connection(s)1250refers to the hardware/software employed to connect the network interface1248to the bus1218. While communication connection1250is shown for illustrative clarity inside computer1212, it can also be external to computer1212. The hardware/software necessary for connection to the network interface1248includes, for exemplary purposes only, internal and external technologies such as, modems including regular telephone grade modems, cable modems, power modems and DSL modems, ISDN adapters, and Ethernet cards or components.

FIG. 13is a schematic block diagram of a sample-computing environment1300with which the present invention can interact. The system1300includes one or more client(s)1310. The client(s)1310can be hardware and/or software (e.g. threads, processes, computing devices). The system1300also includes one or more server(s)1330. Thus, system1300can correspond to a two-tier client server model or a multi-tier model (e.g., client, middle tier server, data server), amongst other models. The server(s)1330can also be hardware and/or software (e.g., threads, processes, computing devices). One possible communication between a client1310and a server1330may be in the form of a data packet adapted to be transmitted between two or more computer processes. The system1300includes a communication framework1350that can be employed to facilitate communications between the client(s)1310and the server(s)1330. The client(s)1310are operably connected to one or more client data store(s)1360that can be employed to store information local to the client(s)1310. Similarly, the server(s)1330are operably connected to one or more server data store(s)1340that can be employed to store information local to the servers1330.