Serialize a Strategy Pattern List of objects with out xsi:type.

G

Guest

As an examle I have a list of Vehicles that I want to serialize. A Vehicle
could have Car or a MotorCycle as derived classes (strategy pattern).

I want to serialize a list of Vechicles xsi:type attribute having the
element names being Vehicle as shown here.

<ArrayOfVehicle>
<Vehicle>
<Wheels>4</Wheels>
<Doors>4</Doors>
</Vehicle>
<Vehicle>
<Wheels>2</Wheels>
<HandleBarStyle>Way cool style.</HandleBarStyle>
</Vehicle>
</ArrayOfVehicle>

I am able to get a List of Vechicles to serialize just fine with the
xsi:type attribute, however, the system that I am sending this data to cannot
accept the attribute and does not need it. I understand for .NET
deserialization would be needed. If I leave the xsi:type in, the schema
validation fails on the destination system and we cannot modify the schema
used for validation. Here is the xml output of what I currently get
including the xsi:type attributes.

<ArrayOfVehicle>
<Vehicle xsi:type="Car">
<Wheels>4</Wheels>
<Doors>4</Doors>
</Vehicle>
<Vehicle xsi:type="MotorCycle">
<Wheels>2</Wheels>
<HandleBarStyle>Way cool style.</HandleBarStyle>
</Vehicle>
</ArrayOfVehicle>

Here is my code:

// Example Controlling method.
private void Example2()
{
Car car1 = new Car();
car1.Doors = 4;
car1.Wheels = 4;

MotorCycle cycle1 = new MotorCycle();
cycle1.HandleBarStyle = "Way cool style.";
cycle1.Wheels = 2;

List<Vehicle> vehicals = new List<Vehicle>();
vehicals.Add(car1);
vehicals.Add(cycle1);

using (XmlTextWriter w = new XmlTextWriter("Example1b.xml", Encoding.ASCII))
{
w.Formatting = Formatting.Indented;


XmlSerializer x = new XmlSerializer(typeof(List<Vehicle>));
x.Serialize(w, vehicals);
}

}

[XmlRoot("vehicle")]
[XmlInclude(typeof(Car)), XmlInclude(typeof(MotorCycle))]
public class Vehicle
{
private int _wheels;

public int Wheels
{
get { return _wheels; }
set { _wheels = value; }
}
}

public class MotorCycle : Vehicle
{
private string _handleBarStyle;

public string HandleBarStyle
{
get { return _handleBarStyle; }
set { _handleBarStyle = value; }
}
}

public class Car : Vehicle
{
private int _doors;

public int Doors
{
get { return _doors; }
set { _doors = value; }
}

}


Thanks for your help,

Tom
 
N

Nick Malik [Microsoft]

First off, if that is all of your code, there's no strategy pattern here.
Your base type is a type of 'thing' not a type of 'algorithm', so call this
what you'd like, there is no strategy pattern here.
http://www.dofactory.com/Patterns/PatternStrategy.aspx

Secondly, this looks a LOT like homework.

Third, if you don't like the XML emitted by the XML serializer, write your
own serializer object.

Fourth, if you want to deserialize the XML in .Net, you need the xsi:type
attribute. Therefore, I'm assuming that either you are not deserializing
the XML in .Net or you need to have an object called Vehicle. Perhaps you
could have an object called Vehicle that actually uses a strategy pattern...
that would work!

Of course, it would require you to know what a strategy pattern actually
encapsulates.

Fifth, this looks a LOT like homework.

--
--- Nick Malik [Microsoft]
MCSD, CFPS, Certified Scrummaster
http://blogs.msdn.com/nickmalik

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
I do not answer questions on behalf of my employer. I'm just a
programmer helping programmers.
--
Tom Krueger said:
As an examle I have a list of Vehicles that I want to serialize. A
Vehicle
could have Car or a MotorCycle as derived classes (strategy pattern).

I want to serialize a list of Vechicles xsi:type attribute having the
element names being Vehicle as shown here.

<ArrayOfVehicle>
<Vehicle>
<Wheels>4</Wheels>
<Doors>4</Doors>
</Vehicle>
<Vehicle>
<Wheels>2</Wheels>
<HandleBarStyle>Way cool style.</HandleBarStyle>
</Vehicle>
</ArrayOfVehicle>

I am able to get a List of Vechicles to serialize just fine with the
xsi:type attribute, however, the system that I am sending this data to
cannot
accept the attribute and does not need it. I understand for .NET
deserialization would be needed. If I leave the xsi:type in, the schema
validation fails on the destination system and we cannot modify the schema
used for validation. Here is the xml output of what I currently get
including the xsi:type attributes.

<ArrayOfVehicle>
<Vehicle xsi:type="Car">
<Wheels>4</Wheels>
<Doors>4</Doors>
</Vehicle>
<Vehicle xsi:type="MotorCycle">
<Wheels>2</Wheels>
<HandleBarStyle>Way cool style.</HandleBarStyle>
</Vehicle>
</ArrayOfVehicle>

Here is my code:

// Example Controlling method.
private void Example2()
{
Car car1 = new Car();
car1.Doors = 4;
car1.Wheels = 4;

MotorCycle cycle1 = new MotorCycle();
cycle1.HandleBarStyle = "Way cool style.";
cycle1.Wheels = 2;

List<Vehicle> vehicals = new List<Vehicle>();
vehicals.Add(car1);
vehicals.Add(cycle1);

using (XmlTextWriter w = new XmlTextWriter("Example1b.xml",
Encoding.ASCII))
{
w.Formatting = Formatting.Indented;


XmlSerializer x = new XmlSerializer(typeof(List<Vehicle>));
x.Serialize(w, vehicals);
}

}

[XmlRoot("vehicle")]
[XmlInclude(typeof(Car)), XmlInclude(typeof(MotorCycle))]
public class Vehicle
{
private int _wheels;

public int Wheels
{
get { return _wheels; }
set { _wheels = value; }
}
}

public class MotorCycle : Vehicle
{
private string _handleBarStyle;

public string HandleBarStyle
{
get { return _handleBarStyle; }
set { _handleBarStyle = value; }
}
}

public class Car : Vehicle
{
private int _doors;

public int Doors
{
get { return _doors; }
set { _doors = value; }
}

}


Thanks for your help,

Tom
 
G

Goran Sliskovic

Nick Malik said:
First off, if that is all of your code, there's no strategy pattern here.
Your base type is a type of 'thing' not a type of 'algorithm', so call this
what you'd like, there is no strategy pattern here.
http://www.dofactory.com/Patterns/PatternStrategy.aspx

Secondly, this looks a LOT like homework.
....

Well, maybe it is homework, however problem lives also in business domain.
Whenever I had to interface to third party via xml, requirements are like OP
has. It is maybe my bad luck. Tipically, people would design that example as
a Vehicle node containing all possible properties for all possible vehicle
types as string nodes inside (one big XML with everything inside). Then lot
of "if" branching is used to determine actual type.

There is use of xml, and then there is abuse of xml. With later being more
often.

Regards,
Goran
 
N

Nick Malik [Microsoft]

Goran Sliskovic said:
...

Well, maybe it is homework, however problem lives also in business domain.
Whenever I had to interface to third party via xml, requirements are like
OP
has. It is maybe my bad luck. Tipically, people would design that example
as
a Vehicle node containing all possible properties for all possible vehicle
types as string nodes inside (one big XML with everything inside). Then
lot
of "if" branching is used to determine actual type.

There is use of xml, and then there is abuse of xml. With later being more
often.

Regards,
Goran

The strategy pattern can be used to solve this problem by creating your own
XML serializer class to create the XML or deserializer class to read the XML
and load the objects. That is the point of the strategy pattern: to
encapsulate an algorithm so that a variation on the 'standard' algorithm can
be used in all the same places, with all the same support, as the 'native'
algorithm.

It is always difficult to deal with XML data that doesn't provide 'clues'
about the variations in type. I've dealt with this in my code as well. It
is not easy and will not suddenly become easy. That said, deserialization
of data from a remote system can often be done by creating a 'superset
class' that contains members that are optional. You load the data using the
standard deserializer into the superset class and then, as you mentioned,
apply logic to determine if actual objects can be derived from that data.
In the process, you populate a more correct derived class in your code.
This is an alternative to using the strategy pattern for deserialization,
but in a sense, it is quite direct and very visible to the developer. It
has a drawback, however, of the fact that the composition rules for classes
are now in two places: in the XML schema and in the interpreter code that
reads the superset data and creates actual objects. Given this fact, I
believe that a custom serializer or deserializer is a more appropriate
solution.

--
--- Nick Malik [Microsoft]
MCSD, CFPS, Certified Scrummaster
http://blogs.msdn.com/nickmalik

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
I do not answer questions on behalf of my employer. I'm just a
programmer helping programmers.
--
 
G

Guest

Hello,

Thanks for the posts (I think). I have to say I'm a bit angered by your
first post. If you were not going to answer the question or ask for
clarification, then why did you reply. All you did is stop other people that
answer newsgroup questions from looking at my post. If I made a mistake in
calling something a strategy pattern when it is not, then by all means please
correct me, but you could be a little more polite rather than trying to fire
on me. As for your "secondly" comment about homework, who cares if this is
homework. Are the newsgroups not for asking questions that you do not know
the answer to. If this was a simple homework question someone would have
answered it correctly by now. Just so you know, this is not a homework
assignment. I just gave this simplified example so readers could focus on
solving the problem instead of needing to learn about the business domain.
The real problem is regarding systems integration for an ecommerce web site
hosted by a 3rd party. I have no control over the xml structure, I just have
to abide by it. Which is part of the problem.

Then there is the question of did I really make a mistake in calling this
problem a strategy pattern. Honestly I'm not sure. The problem I presented
very well may not be a strategy pattern by a technicality. From the
DAOFactory link that you provided couldn't Vechicle be considered a strategy,
with Car and MotorCycle being ConcreteStrategyA and B? If you are looking
for a context, I used List<Vechicles>. I am very interested to learn why
exactly this is not a strategy pattern. Also, if it is not a strategy
pattern, then I would also very much like to learn what pattern it is.
Seriously, I want to learn and would appreciate anyone telling me why the
Vechical example is not a strategy. I don't want to go around calling a
horse a donkey.

Ok, back to the original problem:
The problem is simple, when serializing my List of Vechicles the .NET
XMLSerializer adds the xsi:type attributes to each of the Vechicle XML
elements. I am interested in knowing how to tell the serializer not to
include those xsi:type attributes. I understand that I can write a customize
the serialization, however, I don't want to. I want to either add an
attribute to the Vechical class or pass a value somehow into the
XMLSerializer. Please refer to my original post for xml and code examples.

I also understand the xsi:type attributes are for deserialization (or at
least I believe they are), but I don't care about deserializing, this is how
the 3rd party wants it. So please don't post if you are going to argue the
design of the xml. One it is not up to me, and two it isn't a problem
because there are other attributes being used by the 3rd party for
deserialization on their end.

Thanks you for you time,

Tom
 
N

Nick Malik [Microsoft]

Tom Krueger said:
Hello,

Thanks for the posts (I think). I have to say I'm a bit angered by your
first post. If you were not going to answer the question or ask for
clarification, then why did you reply. All you did is stop other people
that
answer newsgroup questions from looking at my post.

I have no control over other responders. On occasion, in other threads, I
have wished for such control, but alas... ;-)
If I made a mistake in
calling something a strategy pattern when it is not, then by all means
please
correct me, but you could be a little more polite rather than trying to
fire
on me. As for your "secondly" comment about homework, who cares if this
is
homework. Are the newsgroups not for asking questions that you do not
know
the answer to. If this was a simple homework question someone would have
answered it correctly by now. Just so you know, this is not a homework
assignment. I just gave this simplified example so readers could focus on
solving the problem instead of needing to learn about the business domain.

Alas, my 'homework filter' does occasionally catch someone who tries to
simplify a problem to the point where it is no longer clearly a business
problem. I am sorry that I 'charged' your post with the 'homework' label if
in fact it was not.

In my defense, there are hundreds of posts every year from folks who post
their homework problems, verbatim, and ask for someone on the board to
innocently solve it for them. These people are cheating, and some of them
are going to make it through the educational process without learning, and
one or two may very well make it past a job interview to work at my company.
I don't want them to succeed in their efforts to thwart their own learning
process. This is when I mention 'homework.' If I believe that the problem
is homework, I choose not to actually respond with details, but rather with
generalities that should help an actual student to solve their problem
without giving them 'cut and paste text' for their assignment.

I am hopeful that my original answer was useful, if not completely helpful,
in helping you to research potential solutions.
The real problem is regarding systems integration for an ecommerce web
site
hosted by a 3rd party. I have no control over the xml structure, I just
have
to abide by it. Which is part of the problem.

Alas... no one likes this situation.
Then there is the question of did I really make a mistake in calling this
problem a strategy pattern. Honestly I'm not sure. The problem I
presented
very well may not be a strategy pattern by a technicality. From the
DAOFactory link that you provided couldn't Vechicle be considered a
strategy,
with Car and MotorCycle being ConcreteStrategyA and B? If you are looking
for a context, I used List<Vechicles>. I am very interested to learn why
exactly this is not a strategy pattern.

Look at the GoF patterns as different solutions for fairly specific
problems. The problem that 'strategy' is trying to solve is that you have
an algorithm that may vary, and you want to encapsulate that variation in a
way that limits changes to the calling code. Strategy patterns are
therefore specifically trying to encapsulate algorithms. Your Vehicle
structure does not vary in algorithm in a discernable way. It varies in
structure. Therefore, the only way that I can think of to apply Strategy to
that class heirarchy is to consider the algorithm for serializing or
deserializing the data.

Therefore, it is a strategy if you write a custom serializer and/or
deserializer, since that is an algorithm that is encapsulated, thus allowing
for variation.
Also, if it is not a strategy
pattern, then I would also very much like to learn what pattern it is.
Seriously, I want to learn and would appreciate anyone telling me why the
Vechical example is not a strategy. I don't want to go around calling a
horse a donkey.

I'd need to know more about why the data is structured in this way. Your
example is spare, and perhaps that's because you invented it to illustrate
your point. As a result, it is difficult to tell what variation you are
attempting to hide from calling code. If I can understand what variation
you are attempting to encapsulate, perhaps I can point out the pattern.
Until then, it is simply an object heirarchy. Patterns represent 'good' or
'best' practices. Not all practices are good. Therefore, not all
heirarchies can be illustrated as a pattern.

Your problem is especially difficult because your list specifically shows
items as 'Vehicle' but provides elements to a 'Vehicle' item that are not
elements of 'Vehicle' but are, in fact, elements of 'Motorcycle' or 'Car'.
Ok, back to the original problem:
The problem is simple, when serializing my List of Vechicles the .NET
XMLSerializer adds the xsi:type attributes to each of the Vechicle XML
elements. I am interested in knowing how to tell the serializer not to
include those xsi:type attributes. I understand that I can write a
customize
the serialization, however, I don't want to. I want to either add an
attribute to the Vechical class or pass a value somehow into the
XMLSerializer. Please refer to my original post for xml and code examples.

In your case, since you don't want to write a custom serializer, I would
suggest that you create a seperate class that you will serialize. That
class will be called Vehicle but will contain a superset of attributes from
each of the different 'vehicle' classes that your app supports. When it
comes time to serialize the list, convert your elements, one at a time, into
this alternative class, and then serialize from there. Off the top of my
head, I don't remember the attribute to add to an element to note that it
should not be present if it is null, but I'm fairly sure that you can do
this.

//I cannot tell you the attributes you'd need, off the top of my head.
Other respondants?

public class SerVehicle : Vehicle
{
public int Wheels;
public string HandleBarStyle;
}

convert your list to objects of type SerVehicle and then serialize.


--
--- Nick Malik [Microsoft]
MCSD, CFPS, Certified Scrummaster
http://blogs.msdn.com/nickmalik

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
I do not answer questions on behalf of my employer. I'm just a
programmer helping programmers.
--
 
G

Guest

Thanks Nick for the response.

If you or anyone wants to take on this challenge the sample that I have
given can be considered a problem to be solved. Forget about the business
aspects of it. Nick I know you asked for more business information, however,
I'm not asking this question to get alternative solutions, I am interested in
the specific solution to solve this simple (but may not be possible) problem.
I have an alternative solution developed and in place which will work fine,
however, I believe the solution that I am looking for exists and I would like
to know for the next time this situation occurs. If a simple solution does
not exist, then it should be brought to the Microsoft Product teams
attention. I'm not saying that something should be changed, I'm simply
saying that this issued should be thought about if it has not already.

Interestingly what I am more interested in now is our discussion as to
whether this is a strategy pattern or not. Again, I'm not certain that it is
however, I don't see yet how it is not. You say that that an algorithm is
needed and you say that Car and MotorCycle are not algorithms. I guess it
depends on how you define algorithm. My thought is that those creating the
patterns need a generic term to define the structure so I believe algorithm
is being used loosely. Let me ask this, what if we added the method
Accelerate() to Vechical which both Car and MotorCycle them implement. Would
they then be considered algorithms?

You stated "Patterns represent 'good' or 'best' practices. Not all
practices are good. Therefore, not all heirarchies can be illustrated as a
pattern". While I agree this is probably a true statement, I don't see how
it applies here. Are you saying that it is bad practice to call a MotorCycle
a Vehicle. I don't see how you can say such a thing, without knowing the
solution that it is being used for. The example given is a very common
"problem" so there definitely is a name for this pattern, personally as you
know, I think it is called strategy. I cannot believe it is only considered
to be an object hierarchy as you stated. So again, I ask if it is not
strategy then what is it?

Thanks for your responses, I do appreciate them. Just so you know, I don't
intend to be confrontational, but I am interested in learning.

Have a great day,

Tom
 
N

Nick Malik [Microsoft]

Hello Tom,

Sorry for the delay in responding. I was offline due to a family emergency
for a few weeks.

Tom Krueger said:
Thanks Nick for the response.

If you or anyone wants to take on this challenge the sample that I have
given can be considered a problem to be solved. Forget about the business
aspects of it. Nick I know you asked for more business information,
however,
I'm not asking this question to get alternative solutions, I am interested
in
the specific solution to solve this simple (but may not be possible)
problem.

If you mean "does anyone want to write the code for a custom serializer?"
then that would only be a fairly minor challenge. If I had time, I'd take
you up on it, but alas, I do not.

I have an alternative solution developed and in place which will work
fine,
however, I believe the solution that I am looking for exists and I would
like
to know for the next time this situation occurs. If a simple solution
does
not exist, then it should be brought to the Microsoft Product teams
attention.

A simple solution exists. To write a custom serializer and use it to
serialize your objects. Not that difficult. Very patterns based.
Interestingly what I am more interested in now is our discussion as to
whether this is a strategy pattern or not.

The serialization mechanism in .net framework employs a strategy pattern.
This is what allows you to write a custom serializer. The framework will
call your serializer (concrete strategy) instead of the one supplied with
the framework The strategy pattern allows the developer to write their
code where the developer is not aware (and does not need to be aware) of all
the potential plug-in algorithms for a particular use. As long as the
algorithm fits the interface, it can be called.
Again, I'm not certain that it is
however, I don't see yet how it is not. You say that that an algorithm is
needed and you say that Car and MotorCycle are not algorithms. I guess it
depends on how you define algorithm.

no offense, but a Car is not an algorithm. It is an thing, an object. What
you are encapsulating in your example object heirarchy is that you can have
a generic vehicle type that hides the possibility that the concrete object
may be either a car or a motorcycle. Note that it does a poor job of hiding
this detail, since there are members defined on both car and motorcycle that
are specific to the type. This means that the calling code needs to know
that it is calling a car, and not a vehicle, to use that member. This
creates tight coupling. Unless the calling code is specific to the 'car'
type (as it could be if you create a set of related object types like those
created by the abstract factory), then the calling code is coupled to the
car type and you get NOTHING through your inheritance heirarchy.

Object orientation does not provide any benefit if the designer simply looks
for obvious generalizations to place on an object. OO only benefits you if
you intentionally decide that it is in your best interest to hide something
under a generalization. Inheritance for its own sake creates unmaintainable
code.
My thought is that those creating the
patterns need a generic term to define the structure so I believe
algorithm
is being used loosely.

No. It is not. You have clearly not read the Gang-of-Four book or one of
the many books that do a good job of explaining it. Erich Gamma was writing
his Ph.D. thesis, which he published as that book. His words are specific,
scientifically chosen, and boring as h_ll. There is nothing loose about
design patterns.
Let me ask this, what if we added the method
Accelerate() to Vechical which both Car and MotorCycle them implement.
Would
they then be considered algorithms?

The heirarchy that you define is that of a vehicle with specialized bits for
'car' and 'motorcycle'. So, no, you don't magically change a noun into a
verb by adding a method to the class. If on the other hand, you add an
object called 'TankFiller' to the base class, and in your factory, and
'TankFiller' is a base class with three concrete children called
'RobotFiller,' 'HumanFiller,' and 'CoyoteFiller' and your factory would
decide, when creating the motorcycle object, which filler class to associate
with it, and a method in either the base 'Vehicle' class or the concrete
'Motorcycle' class simply called 'TankFiller.DoYourStuff()' in order to
increase the fuel supply in the vehicle, then I'd say that you have created
and consumed a strategy pattern.
You stated "Patterns represent 'good' or 'best' practices. Not all
practices are good. Therefore, not all heirarchies can be illustrated as
a
pattern". While I agree this is probably a true statement, I don't see
how
it applies here.

I meant to say that you illustrated a heirarchy and, indirectly, asked 'what
pattern is this?' My answer: it is not a pattern because your design does
not illustrate a practice that I would encourage in anyone. If, in fact,
you were to present that class design to me in an architectural review, I'd
be fairly curious about what you were trying to accomplish. If you couldn't
answer there any better than you have answered here, I'd suggest alternative
heirarchies for the solution. In other words, I'd ask you not to write that
code.
Are you saying that it is bad practice to call a MotorCycle
a Vehicle.

No. If you want to encapsulate vehicles, it is perfectly appropriate to
create a vehicle base class and create child classes for 'automobile' and
'motorcycle'. However, you then proceed to add methods to each of the child
classes that are mutually exclusive. That indicates that the calling code
would need to be tightly coupled to the concrete type rather than to the
abstraction, in order to use the methods. That is bad practice.
I don't see how you can say such a thing, without knowing the
solution that it is being used for. The example given is a very common
"problem"

The example is a code snippet. If you have a common problem that you wish
to be answered by a pattern, try to frame your problem in the following
terms: "I have a situation where X is in common and Y varies. I want to
hide the variation from code that needs only know about X. How do I do it?"
If your 'X' is a data-only object, you have implemented a DTO pattern (Data
Transport Object). If your X is an algorithm that can be applied by the
calling code (good example: bubble sort vs. QuickSort) without knowing the
details of the algorithm, then you have a strategy pattern. If your X is a
sequence of related conditions that need to be evaluated in order, then you
may have a decorator or a chain of responsibility pattern.

The key to framing your problem in terms of commonality and variability is
that you are performing a very basic and extremely powerful OOA technique
called, surprisingly, Commonality-Variability Analysis or CVA. See this
article for more details on this powerful technique. This article is a
chapter in a book that I highly recommend called Design Patterns Explained
by Shalloway and Trott:
http://www.netobjectives.com/ezines/ez0407NetObj_Commonality_and_Variability_Analysis.pdf
so there definitely is a name for this pattern,

I am not as familiar with the names of anti-patterns as I am with patterns,
so if there is a name, I cannot recall it off the top of my head. ;-)

I'm doing my best to be respectful of you and your question. I know that
you mean well. However, as far as I can tell, and I've taught a few courses
on OO Design Patterns over the years, the snippet that you presented does
not represent a good practice, and therefore does not appear in the canon of
design patterns. If I am wrong, I invite anyone to submit the name and
description of a design pattern (or link to one) that is adequately
described by the OP's code snippet in this thread.

Tom, perhaps I can offer some more detailed information.

The following sites are good for introducing code-specific bits of design
patterns
http://www.dofactory.com/Patterns/Patterns.aspx
http://home.earthlink.net/~huston2/dp/patterns.html

In addition to the book mentioned above, another very good book on design
patterns is Head First Design Patterns
http://www.oreilly.com/catalog/hfdesignpat/

I hope that this begins a journey for you. I mean that in the nicest and
most generous way possible. Honest. Reading about, then learning, then
studying, and then teaching design patterns changed my career completely. I
hope that you find design patterns to be as powerful as I have.

--
--- Nick Malik [Microsoft]
MCSD, CFPS, Certified Scrummaster
http://blogs.msdn.com/nickmalik

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
I do not answer questions on behalf of my employer. I'm just a
programmer helping programmers.
--
 
Top