Library Namespaces

It's unlikely that you'll use every namespace in the .NET Framework class library. (That's not to say you won't—it's just unlikely.) Instead, you'll probably work with the subset of namespaces that follow.

I will start with the root namespace System and then progress alphabetically through the most common namespaces. This chapter will not provide you everything you need to implement the classes within a namespace. Instead, it will give you an understanding of what functionality resides within it. If you want a deeper understanding of all the details of the classes within a namespace, and I do not cover the namespace in the subsequent chapters, then I suggest you peruse the documentation provided with the .NET Framework, as it is remarkably well done.


Originally, I was going to include the Microsoft root namespace in this chapter, but when I examined it, I found that it went against the platform-independent direction of this book. The classes found in the Microsoft root namespace are very Microsoft Windows-specific.


The System namespace is the root of the .NET Framework class library namespace hierarchy. The namespace is defined within the mscorlib.dll assembly.

Unlike the other namespaces of the .NET Framework class library, which focus on a particular area of functionality, the System namespace is more a mishmash of core data types and basic functionality that is needed by the rest of the namespace hierarchy.

The most important class within the System namespace would probably be the Object class because it is the root of all other classes found within the class library. When you create managed (__gc) classes of your own, the Object class is inherited by default if you do not specify a parent class. Remember, because managed (__gc) classes can only inherit from other managed (__gc) classes, ultimately your class will inherit the Object class.

Some of the other common functional areas covered by the System namespace are as follows:

  • Primitive types, such as Byte, Int32, Double, and String

  • Arrays

  • Data type conversion

  • Attributes

  • Delegates

  • Enums

  • Events

  • Exceptions

  • Garbage collection

  • Math

  • Operating system information

  • Random numbers

As you can see, you have already covered most of these areas in prior chapters.

Normally, a developer would allow garbage collection to be handled automatically by the CLR because it's a well-tuned process. For some applications, there might be occasions when garbage collection simply doesn't run often enough or at the times wanted by the developer. For these cases, the .NET Framework class library provides the System::GC class. This class doesn't allow the programmer the ability to change the garbage collection process, but it changes the triggering process and helps determine what memory is garbage.

The Math class is an important class that I haven't yet covered. It's made up of a set of static data type overloaded member methods such as Abs(), Exp(), Max(), and Sin(). These methods are easy to use. For example, to find the square root of a number, simply code the following:

 double val = 16, root; root = System::Math::Sqrt( val ); 

Another class that can come in handy is System::OperatingSystem. This class provides information such as the version and platform identifier. The System::Version class is used to hold the four-part version (Build, Major, Minor, and Revision) used by the .NET Framework.

Being a games program developer at heart, one of the first classes I went in search of was the random number generator. System::Random provides random numbers in both integer and floating-point formats.

    System::Random &rand = *new System::Random();    Int32  Int32RandomNumber  = rand.Next(1, 10);  // between 1 and 10 inclusive    Double DoubleRandomNumber = rand.NextDouble(); // between 0.0 and 1.0 


There are, in fact, two sets of collections available to the .NET Framework programmer: System::Collections and System::Collections::Specialized. As the namespaces suggest, the first set contains generic collection types and the second contains collection types with a more specific purpose. You will find the more common and frequently used System::Collections in the mscorlib.dll assembly, whereas the less frequently used System::Collections::Specialized is in the system.dll assembly.

Because collections are an integral part of most .NET software development, Chapter 7 goes into many of these collections in much greater detail.

Table 5-1 shows you at a quick glance what collection types are found in the System::Collections namespace.

Table 5-1: Collection Types Found Within System::Collections




An array that grows dynamically


An array of bit values (either 1 or 0)


A collection of key/value pairs organized based on a hash code of the key


A collection of first-in-first-out objects


A collection of key/value pairs sorted by key and accessible by either key or index value


A collection of first-in-last-out objects

Table 5-2 lists all the collection types that you will find in System::Collection::Specialized. As you can see, you will probably use these collections less often, but the .NET Framework class library is nice enough to provide them if you ever end up needing to use one of them.

Table 5-2: Collection Types Found Within System::Collections::Specialized




A small collection that will represent Boolean or small integers within 32 bits of memory


A collection that switches from a list dictionary, when small, to a hash table, when larger


A singular link list recommended for lists of ten objects or less


A collection of string key/value pairs organized on the string key and accessible by either string key or index


A collection of strings


A hash table with the key strongly typed to be a string


The System::Data namespace is the root for all ADO.NET classes found in the .NET Framework class library. ADO.NET is a new data access technology written for the .NET Framework and meant to replace the use of ADO where it is important to remain entirely within .NET. Accessing a database is a very common practice in software development, so you might think that it would be included in the mscorlib.dll default assembly, but you would be wrong. You need to reference two different assemblies. The first is the System.Data.dll assembly, which makes sense now that you know that it's a separate assembly. The second is the System.Xml.dll assembly. I'll go into detail about why this assembly is needed later in Chapter 12. A simple reason is that ADO.NET uses a lot of XML and exposes member methods that use XML. To include these assemblies, if you don't remember, simply add these lines to the top of your source:

 #using <> #using <System.Xml.dll> 

The System::Data namespace comprises most of the classes that make up the ADO.NET architecture. The classes that represent the specific databases to which ADO.NET will connect are missing. These classes are known in ADO.NET-speak as data providers. Currently, ADO.NET supports multiple data providers. The data providers found in the System::Data namespace are

  • System::Data::SqlClient: For Microsoft SQL Server database access

  • System::Data::Odbc: For ODBC database access

  • System::Data::OleDb: For OLE DB database access

  • System::Data::OracleClient: For Oracle database access

Many classes are contained within the System::Data namespace. Depending on your database needs, you may require the use of many of these classes. Most likely, though, you'll only have to rely on a few. Table 5-3 provides a list of the more common classes that you may encounter. But don't despair immediately if the specific database access functionality you require isn't in this table. Chances are that there's a class within this namespace that does what you need because System::Data is quite thorough.

Table 5-3: Common System::Data Namespace Classes




A constraint enforced on a data column—for example, a foreign key constraint or a unique key constraint.


A strong typed column in a data table.


A relationship between two data tables within the data set.


A collection of all the data relations for a data set.


A row of data in a data table.


An in-memory cache of all retrieved data from the data provider.


An in-memory cache of a single data table within the data set.


A collection of all data tables within the data set.


A customized view of a data table used for sorting, filtering, searching, editing, and navigation. This view can be bound to higher-level constructs such as GUI tables and lists.

You will look at the System::Data and its two data provider namespaces when you learn about ADO.NET in great detail in Chapter 12.


Executing a program in the CLR environment has its advantages, one of those being readily available diagnostic information. True, it is possible to code your traditional C++ to capture diagnostic information but, with .NET, you get it virtually free with the classes within the System::Diagnostics namespace. The only catch is that because this namespace is not used that frequently, you need to implement the system.dll assembly:

 #using <System.dll> 

The diagnostic functionality available ranges from simply allowing viewing of event log files and performance counters to allowing direct interaction with system processes. An added bonus is that this namespace provides classes to handle debugging and tracing.

Two main classes handle event logs in the System::Diagnostics namespace. Event Log provides the ability to create, read, write, and delete event logs or event sources across a network. EntryWrittenEventHandler provides asynchronous interaction with event logs. Numerous supporting classes provide more detailed control over the event logs.

It is possible to monitor system performance using the class PerformanceCounter. It is also possible to set up your own custom performance counters using the class PerformanceCounterCategory. You can only write to local counters, but the restriction is eased when it comes to reading counters. Of course, you need to have the right to access the remote machine from where you want to read the counter.

The System::Diagnostics namespace provides an amazing amount of power when it comes to processes. For example, the Process class has the ability to start, monitor, and stop processes on your local machine. In fact, the Process class can also monitor processes on remote machines. Added to this are the ProcessThread and ProcessModule classes, which allow you to monitor the process threads and modules. It is also possible to control how a process runs by having control over things such as arguments and environment variables, and input, output, and error streams using the ProcessStartInfo class.

Almost every programmer uses debug and/or trace statements within his code. So common is the practice that the .NET Framework class library includes the Debug and Trace classes to ease your coding life. Syntactically, the Debug and Trace classes are nearly identical. The difference between them lies in the time of compilation and the current development environment being used. Trace statements are executed no matter what the environment (unless you code otherwise), whereas debug statements are only included and executed while within the Debug environment.

Table 5-4 provides you with a quick lookup table of the classes you might find useful within the System::Diagnostics namespace.

Table 5-4: Common System::Diagnostics Namespace Classes




Methods and properties to help debug a program


Provides communication to a debugger


The default output method for Trace


Handler to provide asynchronous interaction with event logs


Provides interaction with event logs


Provides access to system performance counters


Creates and provides access to custom performance counters


Provides access to local and remote processes and the ability to start and stop local processes


Provides access to process modules


Provides control over the environment for which a process starts


Provides access to process threads


Provides methods and properties to help trace a program


System::DirectoryServices is a small namespace providing easy access to Active Directory. Not the most commonly used namespace, it has been placed in its own assembly, System.Directoryservices.dll. To add the namespace, you require the following code at the top of your source:

 #using <System.Directoryservices.dll> 

It is assumed that you have prior knowledge of Active Directory before you use the class but, in a nutshell, here is how to use the class. First, you use the class DirectoryEntry constructor to get access to a node or object within Active Directory. Then, with the DirectoryEntry node and some help classes, you are now capable of activities such as creating, deleting, renaming, setting passwords, moving a child node, and enumerating children.

You can use the classes in this namespace with any of the Active Directory service providers. The current providers are

  • Internet Information Services (IIS)

  • Lightweight Directory Access Protocol (LDAP)

  • Novell NetWare Directory Service (NDS)

  • Windows NT

Another class that you might find of some use in System::DirectoryServices is the DirectorySearcher class. This class allows you to perform a query against an Active Directory hierarchy. Unfortunately, as of now only LDAP supports DirectorySearcher.


Computer software without some form of graphics is nearly a thing of the past, especially in the PC world. The .NET Framework relies on a technology named GDI+ to handle graphics. GDI+ is easy to use. It is designed to handle the myriad of graphic adapters and printers in a device-independent fashion, thus saving you from having to worry about coding for each graphic device on your own. Of course, this is not a new concept as Windows has had a Graphical Device Interface (GDI) since its earliest versions. Those of you from the GDI world should see a considerable simplification of how you now have to code graphics. But you will also find a huge increase in added functionality.

System::Drawing provides the core graphic classes of GDI+, whereas the following four other child namespaces provide more specialized graphics capabilities:

  • System::Drawing::Drawing2D: Adds advanced two-dimensional (2D) and vector graphics

  • System::Drawing::Imaging: Adds advanced GDI+ imaging

  • System::Drawing::Printing: Adds print-related services

  • System::Drawing::Text: Adds advanced GDI+ typography

Every System.Drawing namespace requires that you add the System.Draw.dll assembly to the top of your source:

 #using <System.Drawing.dll> 

I'll go into GDI+ software development in detail in Chapter 11, but for those of you who can't wait that long, here's a brief summary of the functionality.

The core of all GDI+ classes can be found in the System::Drawing namespace. This large namespace contains classes to handle things ranging from a point on the graphics device all the way up to loading and displaying a complete image in many graphic file formats, including BMP, GIF, and JPEG.

The key to all graphics development is the aptly named Graphics class. This class basically encapsulates the graphics device—for example, the display adaptor or printer. With it you can draw a point, line, polygon, or even a complete image. When you use the Graphics class with other System::Drawing classes, such as Brush, Color, Font, and Pen, you have the means to create amazing and creative images on your display device.

Though you can do almost any 2D work you want with System::Drawing, the .NET Framework class library provides you with another set of classes found within the System::Drawing::Drawing2D that allows for more fine-tuned 2D work. The basic principle is similar to the "connect-the-dots" pictures that you did as a kid. The image you want to draw is laid out in 2D space by drawing straight and curved lines from one point to another. Images can be left open or closed. They can also be filled. Filling and line drawing can be done using a brush and/or using a color gradient.

The System::Drawing namespace can handle most imaging functionality. With the System::Drawing::Imaging namespace, you can add new image formats that GDI+ does not support. You can also define a graphic metafile that describes a sequence of graphics operations that can be recorded and then played back.

GDI+ can display (or, more accurately, print) to a printer. To do so is very similar to displaying to a monitor. The difference is that a printer has many different controls that you will not find on a monitor—for example, a paper source or page feed. All these differences were encapsulated and placed into the System::Drawing::Printing namespace.

Nearly all the functionality to handle text is located within the System::Drawing namespace. The only thing left out and placed in the System::Drawing::Text namespace is the ability to allow users to create and use collections of fonts.


The System::Globalization namespace contains classes that define culture-related information, such as language, currency, numbers, and calendar. Because globalization is a key aspect of .NET, the namespace was included within the mscorlib.dll assembly.

You will cover globalization when you learn about assembly programming in Chapter 17. The CultureInfo class contains information about a specific culture, such as the associated language, the country or region where the culture is located, and even the culture's calendar. Within the CultureInfo class, you will also find reference to the date, time, and number formats the culture uses. Table 5-5 shows some of the more common classes within the System::Globalization namespace.

Table 5-5: Common System::Globalization Namespace Classes




Specifies how to divide time into pieces (for example, weeks, months, and years)


Contains specific information about a culture


Specifies how dates and times are formatted


Specifies how numbers are formatted


Contains information about the country and region


Maps a string to its sort key


Specifies the properties and behaviors of the writing system


If you are not using a database to retrieve and store data, then you are most probably using file and/or stream input and output (I/O). Of course, it is completely possible that you are using a database and file and stream I/O within the same application. As you can guess by the System::IO namespace's name, it handles the .NET Framework library class's file and stream I/O. To access System::IO, you need to reference the mscorlib.dll assembly:

 #using <mscorlib.dll> 

Typically when you deal with the System::IO namespace's classes, you are working with files and directories on your local machine and network, or streams of data probably via the Internet. These, however, are not the only uses of the classes found within the System::IO namespace. For example, it is possible to read data from and write data to computer memory, usually either a string buffer or a specific memory location.

You will be going into the .NET Framework class library's I/O capabilities in some detail in Chapter 8. For now, Table 5-6 shows some of the more common classes that you might come across in the System::IO namespace.

Table 5-6: Common System::IO Namespace Classes




Reads in .NET primitive types from a binary stream.


Writes out .NET primitive types to a binary stream.


A collection of static methods for creating, moving, and enumerating directories.


A collection of instance methods for creating, moving, and enumerating directories.


A collection of static methods for creating, copying, deleting, moving, and opening files. It also can be used in the creation of a FileStream.


A collection of instance methods for creating, copying, deleting, moving, and opening files. It also can be used in the creation of a FileStream.


An exception that is thrown when a file on a disk is not found.


Provides support for both synchronous and asynchronous read and write operations to a stream.


Monitors and then raises events for file system changes.


An exception that is thrown when an I/O exception occurs.


Provides support for reading and writing a stream of bytes to memory.


Provides support for operations on a String that contains a file or directory.


Reads a UTF-8 encoded byte stream from a TextReader.


Writes a UTF-8 encoded byte stream to a TextWriter.


Reads a String using a TextReader.


Writes a String using a TextWriter.


An abstract reader class that can represent a sequence of characters.


An abstract writer class that can represent a sequence of characters.


This namespace will be hidden from most Web developers using .NET, as they will most likely use ASP.NET's higher-level extraction of Internet communication. For those of you who are more intimate with the networks, the .NET Framework class library has provided the System::Net and System::Net::Sockets namespaces. To access both the System::Net and System::Net::Sockets namespaces, you need to reference the system.dll assembly near the top of your code:

 #using <system.dll> 

The System::Net namespace provides a simple programming interface for many of today's network protocols. It enables you to do things such as manage cookies, make DSN lookups, and communicate with HTTP and FTP servers.

If that is not intimate enough for you, then the System::Net::Sockets namespace provides you with the ability to program at the sockets level.

For those of you who want to program your network at this lower level, Table 5-7 shows some of the more commonly used System::Net and System::Net::Sockets classes.

Table 5-7: Common System::Net and System::Net::Sockets Namespace Classes




Contains an authentication message specifying whether a client is authorized to access the server


A set of properties and methods to handle cookies


Provides domain name resolution functionality


A global default proxy instance for HTTP requests


Specifies the HTTP version supported by the HttpWebRequest and HttpWebResponse


Provides an HTTP implementation of WebRequest


Provides an HTTP implementation of WebResponse


Contains an Internet protocol address


Provides credentials for password-based authentication schemes


Provides connection management for Internet connections


Controls the rights to create or connect to a socket


Provides a Berkeley socket interface


Provides a client for a TCP network service


Listens for TCP client connections on a TCP network service


Provides a UDP network service


Provides methods for sending and receiving data over a network


Controls the rights to HTTP resources


Most of the time when you develop code, it will involve static loading of assemblies and the data types found within. You will know that, to execute properly, application X requires class Y's method Z. This is pretty standard and most programmers do it without thinking.

This is the normal way of developing with the .NET Framework class library as well. There are times, though, that a developer may not know which class, method, or other data type is needed for successful execution until the time that the application is running. What is needed is dynamic instance creation of data types. With the .NET Framework class library, this is handled by the classes within the System::Reflection namespace found within the mscorlib.dll assembly:

 #using <mscorlib.dll> 

The System::Reflection namespace provides a class that encapsulates assemblies, modules, and types. With this encapsulation, you can now examine loaded classes, structures, methods, and so forth. You can also create dynamically an instance of a type and then invoke one of its methods, or access its properties or member variables.

You will explore System::Reflection in more detail when you examine assembly programming in Chapter 17. Table 5-8 shows some of the more common classes that you might use within the System::Reflection namespace.

Table 5-8: Common System::Reflection Namespace Classes




Defines an assembly


Provides access to all the parts of an assembly's name


A remotable version of AssemblyName


Selects a method, property, etc., and converts its actual argument list to a generic formal argument list


Provides access to the constructor's attributes and metadata


Provides access to the event's attributes and metadata


Provides access to the field's attributes and metadata


Provides access to the member's attributes and metadata


Provides access to the method's attributes and metadata


Defines a module


Provides access to the parameter's attributes and metadata


Provides a wrapper class for a pointer


Provides access to the property's attributes and metadata


Provides a wrapper for an object, and then delegates all methods to that object


The .NET Framework can handle resources in several different ways: in an assembly, in a satellite assembly, or as external resource files and streams. The handling of resources within the .NET Framework class library for any of these three ways lies in the classes of the System::Resources namespace. Handling resources is a very common task, so it was placed within the mscorlib.dll assembly:

 #using <mscorlib.dll> 

Resources can be fixed for an application divided by culture. You will examine resources programming when you cover assembly programming in Chapter 17. You will be dealing mostly with three classes within the System::Resources namespace, as shown in Table 5-9.

Table 5-9: Common System::Resources Namespace Classes




Provides the ability to access culture-specific resources from an assembly or satellite assembly. It can also read from a specified resource file or stream.


Provides the ability to read from a specified resource file or stream.


Provides the ability to write to a specified resource file or stream.


Multithread programming can be a very powerful feature, as it allows for more optimal CPU usage and better response time. Very seldom is a computer at 100 percent usage, and running more than one thread concurrently can help you get more out of your CPU.

The .NET Framework has built-in multithreading. In fact, an important feature of .NET, garbage collection, is handled using multithreading. The .NET Framework exposes its multithreading capabilities with the classes found in the System::Threading namespace. Multithreading, being an important and frequently used feature of the .NET Framework, is found in the mscorlib.dll assembly:

 #using <mscorlib.dll> 

The System::Threading namespace provides a class to manage groups of threads, a thread scheduler, a class to synchronize mutually exclusive threads, and an assortment of other functionalities to handle multithreading. I will cover multithreading in Chapter 16. For now, Table 5-10 lists all the common classes in the System::Threading namespace that you might use.

Table 5-10: Common System::Threading Namespace Classes




Provides atomic operations for a shared variable across multiple threads


Provides a lock for critical sections of a thread, allowing for synchronized access


Provides synchronized access to shared resources across mutually exclusive threads


Provides a lock that allows a single writer for many readers


Creates and controls threads


Provides a pool of efficient worker threads that are managed by the system


Provides the ability for threads to execute at discrete intervals


The System::Web namespace and the hierarchy of namespaces below it make up a major portion of the .NET Framework class library. This makes sense, as .NET came into being because of the Internet and the World Wide Web.

The System::Web hierarchy is too massive to cover fully here, so I'll leave it to the .NET Framework documentation to provide any detailed explanations you need of any particular class. The .NET Framework breaks Web development into two pieces: Web applications and Web services, which you'll examine in Chapters 14 and 15, respectively. These chapters really just scratch the surface of the functionality available to you as a .NET Web developer.

Table 5-11 will help you to navigate through the myriad of classes provided by the System::Web namespace hierarchy by providing you with a list of some of the more common namespaces (you read that right, namespaces) that you might use.

Table 5-11: Common System::Web Hierarchy Namespaces




Contains classes to handle browser-server communications. This namespace contains HttpRequest and HttpResponse to handle the HTTP dialog between the browser and the Web server.


Contains the cache class used to provide caching of frequently used data on the Web server.


Contains classes to help set up the ASP.NET configuration.


Provides the ability to host managed applications that reside outside of the Microsoft Internet Information Services (IIS).


Contains classes to create and send e-mail using either the SMTP mail service built into Microsoft Windows 2000 or an arbitrary SMTP server.


Contains classes to handle ASP.NET security in Web applications.


Contains classes to create and implement Web services using ASP.NET and XML Web service clients.


Contains classes to store the data specific to a client within a Web application, giving to the user the appearance of a persistent connection.


Contains classes and interfaces to create server controls and pages for Web applications.


Contains classes to create HTML server controls on Web Form pages of Web applications.


Contains classes to create Web server controls on Web pages of Web applications.


Visual Basic has been using forms for many versions, and Windows Forms is modeled on Visual Basic's form technology, but with a much finer grain of control. Normally you will create Windows Forms using a drag-and-drop tool but you also have full access to all aspects of the Win form within your code.

As of the current release, Windows Forms and Windows-based GUI applications are pretty much synonymous. On the other hand, if the .NET Framework starts to get ported to other platforms, as it can be, then a Windows Form will be more equivalent to a GUI application.

First off, all the classes that make up the .NET Windows Forms environment are actually found within the System::Windows::Forms namespace. This namespace is large, containing around 400 different types (classes, structures, enumerations, and delegates). You probably will not use every type within the namespace, but there is a good chance that you may use a large number of them, especially if your Windows Form has any complexity involved.

You will cover Windows Forms in detail in Chapters 9 and 10, but you will also see them used many times in subsequent chapters. For those of you who want a head start, Table 5-12 shows a good number of common classes that you will become quite familiar with if you plan to build Windows Forms.

Table 5-12: Common System::Windows::Forms Namespace Classes




Provides static methods and properties for managing an application


Represents a Windows Forms Button control


Represents a Windows Forms CheckBox control


Represents a Windows Forms CheckListBox control


Provides methods to place data in and retrieve data from the system clipboard


Represents a Windows Forms ComboBox control


Represents the base class of all controls in the Windows Forms environment


Represents a Windows Forms cursor


Represents a window or dialog box, which makes up part of the application's user interface


Represents a Windows Forms Label control


Represents a Windows Forms label control that can display a hyperlink


Represents a Windows Forms ListBox control


Represents the base functionality of all Windows Forms menus


Represents a Windows Forms PictureBox control


Represents a Windows Forms RadioButton control


Represents a Windows Forms RichTextBox control


Represents a Windows Forms ScrollBar control


Represents a Windows Forms StatusBar control


Represents a Windows Forms TextBox control


Represents a Windows Forms ToolBar


Represents a hierarchical display list of TreeNodes


XML is a key component of the .NET Framework. Much of the underlying technological architecture of .NET revolves around XML. No matter what type of application you plan on developing, be it for the Web or a local machine, there is a good chance that somewhere in your application XML is being used. You just might not be aware of it. Because of this, there are a lot of specialized XML classes available to a .NET developer.

To provide XML support to your .NET applications requires the addition of the System.Xml.dll assembly to the top of your source code:

 #using <System.Xml.dll> 

The .NET Framework provides a developer two different methods of processing XML data: a fast, noncaching, forward-only stream, and a random access in-memory Document Object Model (DOM) tree. You will cover both methods in Chapter 13. You will also see a little bit of XML in Chapter 15.

Table 5-13 shows all of the .NET Framework class library's XML-related classes that fall within the System::Xml namespace hierarchy.

Table 5-13: Common System::Xml Namespace Classes




All the core classes needed to create, read, write, and update XML


Provides XML Schema support


Provides the ability to serialize .NET managed objects to and from XML


Provides support for the XPath and evaluation engine


Provides support for Extensible Stylesheet Transformations (XSLT)

Managed C++ and. NET Development
Managed C++ and .NET Development: Visual Studio .NET 2003 Edition
ISBN: 1590590333
EAN: 2147483647
Year: 2005
Pages: 169 © 2008-2017.
If you may any questions please contact us: