static void Main(string[] args)
        {
            string line;

            // this implementation of the observer pattern creates a real time
            // monitor, and attaches to logger,and screen printer concrete observers.
            // the emailer concrete observer is left out here.
            RtmDataGatherer rtm = new RtmDataGatherer("CSV Eater RTM");

            rtm.Attach(new LoggerObserver());
            rtm.Attach(new ScreenPrinterObserver());

            // setting up to send multicast
            Socket     mdpSocket = CommsTools.SetUpMCastSendSocket();
            IPEndPoint mcastEp   = new IPEndPoint(IPAddress.Parse("224.5.6.7"),
                                                  Convert.ToInt32(ConfigurationManager.AppSettings["send_port"]));

            Console.WriteLine("CSV Eater Service Started - (Sending Using MultiCast)");
            Thread.Sleep(3000);  // relax a moment while the receiver starts up

            // read from the csv
            var stream = File.OpenRead(
                ConfigurationManager.AppSettings["csvpath"]);
            var streamReader = new StreamReader(stream);

            while ((line = streamReader.ReadLine()) != null)
            {
                try
                {
                    // this method will throw the BadOrderInput exception if the
                    // order format doesn't match the required pattern
                    CommsTools.sendOrderDataToOME(line, mdpSocket, mcastEp);
                    rtm.SetMessage("sending: " + line);
                    rtm.Notify();
                }
                catch (BadOrderInput e)
                {
                    // simply skipping and going on to the next CSV line, the exception
                    // itself logs the error
                }

                // this just keeps the orders from all zipping by too fast to see
                Thread.Sleep(Convert.ToInt32(ConfigurationManager.AppSettings["order_send_delay"]));
            }

            // telling receiver we're all done
            CommsTools.SendMCastData("-1,-1,-1,-1,-1", mdpSocket, mcastEp);  // send quit signal
            Console.WriteLine("reached end of file, sent quit signal");
            mdpSocket.Close();
            Environment.Exit(0);
        }
        // this code uses the factory pattern to create new orders for sending on the the OME.
        static void Main(string[] args)
        {
            Common.CommsTools.SetUpMCastSendSocket();
            Socket     mdpSocket = CommsTools.SetUpMCastSendSocket();
            IPEndPoint mcastEp   = new IPEndPoint(IPAddress.Parse("224.5.6.7"),
                                                  Convert.ToInt32(ConfigurationManager.AppSettings["send_port"]));
            TraderOrderCreator tocBuy  = new TraderBuyOrderCreator();
            TraderOrderCreator tocSell = new TraderSellOrderCreator();
            TraderOrder        to;
            string             order = "";

            Console.WriteLine("Trader Tool");

            while (true)
            {
                Console.Write("hit enter to begin a trade.");
                Console.ReadLine();

                Console.Write("Buy or Sell [B|S]: ");
                string buyorsell = Console.ReadLine();

                if (buyorsell == "B")
                {
                    // using factory pattern to make orders
                    to = tocBuy.MakeTradeOrder();
                }
                else if (buyorsell == "S")
                {
                    // using factory pattern to make orders
                    to = tocSell.MakeTradeOrder();
                }
                else
                {
                    Console.WriteLine("must be B or S, hit enter to continue.");
                    continue;
                }

                Console.Write("Symbol [MSFT]: ");
                to.SetSymbol(Console.ReadLine(), "MSFT");
                Console.WriteLine(to.GetSymbol());

                Console.Write("purchase type [Regular]:");
                to.SetPurchaseType(Console.ReadLine(), "Regular");
                Console.WriteLine(to.GetPurchaseType());

                Console.Write("price: ");
                to.SetPrice(Console.ReadLine());

                Console.Write("quantity: ");
                to.SetQuantity(Console.ReadLine());

                Console.WriteLine("your order: " + to.GetOrderString());
                Console.Write("OK? [Y|n]");
                string temp = Console.ReadLine();

                if (temp == "" || temp == "Y")
                {
                    try
                    {
                        CommsTools.sendOrderDataToOME(to.GetOrderString(), mdpSocket, mcastEp);
                        Console.WriteLine("Order sent!");
                    }
                    catch (BadOrderInput e)
                    {
                        Console.WriteLine("bad input, no order sent.");
                    }
                }
                to = null;
                Console.WriteLine("hit enter to continue.");
                Console.ReadLine();
                Console.Clear();
            }
        }