Jan 28, 2008

Job Done!

I think I made it finally. The osCommerce 2 vShop import was made this afternoon. Just waiting QA test now.
>

Jan 22, 2008

.NET C# to parse MySQL queries? Impossible? Pavel can make it ;) (with some ifs and buts offcourse ;)

The most interesting task in my career came the end of the last week. As a Vizibility employee I was asked if I can port osCommerce live site to out vShop solution (http://www.vizibility.co.uk/tmenu/vshop.asp) The interesting thing is that I had no access to osCommerce nor did I ever worked with it. What's even more chalenging - osCommerce database was given to me as SQL queries, something like :

drop table if exists table ;
create table table (
-- Some things here ...
);

insert into table () values ( );

As a normal software developer so there were 3 big chalanges:

1. How to parse this SQL thing (it is MySQL) ?
2. How to figure out
the osCommerce Logic ?
3. How to port all those things as a script so it can be applied to our live servers by the support team?


It's really chalanging don't you think? First I thought it will be a good step to install fresh copy of osCommerce, import the products and try to port them as CSV or something. But then I understood it will take too much time, so I decided to parse the SQL queries on my own and store them in a predefined objects like tables, rows and so on and so on. Then I could easilly transfer them as a text files in the format we needed.

And I almost made it - the parsing methods are done (I was able to parse this thing in a day but some bugs still appear).

Seems the more I work on our shopping solution the more easier I can understand other's shopping solutions.

Great task in a great company!

Jan 21, 2008

5 minutes C# code to open Web.Config from Windows Forms application.

In my previous post about IIS, Virtual Directories and Directory Services you saw how can you obtain the sites per IIS instance as well sa all the root virtual directories. Now it is time to show you how can you obtain the Web.Config file for a root directory.

At first glance I thought it will be easy, I thought I will simply need declare the following:

using System.Web.Configuration;

And / or :

using System.Configuration;

Well it's not quite this way. In order to load web.config file from a windows forms application you need to have some kind of context to be used or, in other words, file mapping.

The following method takes two parameters : path to the root directory and DirectoryEntry, representing the root directory
object (you can see my previous post ( Get IIS sites and virtual directories with .NET / C# / Directory Services ) learn how to obtain DirectoryEntry for a web root directory.
And here is the method:

      
List < string []> GetWebConfigAppSettings( string Path, DirectoryEntry entry)
       {
            
List < string []> items = new List < string []>();
            
if (entry.Properties[ "Path" ].Value != null )
            {
               
FileInfo fiWebConfig = new FileInfo (entry.Properties[ "Path" ].Value + @"\web.config" );
               
if (fiWebConfig.Exists)
                {
                  
WebConfigurationFileMap fm = new WebConfigurationFileMap ();
                   System.Collections.
Hashtable props = new System.Collections. Hashtable ();
                  
foreach (System.DirectoryServices. PropertyValueCollection property in entry.Properties)
                   {
                        
string propertyName = property.PropertyName;
                        props.Add(propertyName, property.Value);
                   }
                  
VirtualDirectoryMapping mapping = new VirtualDirectoryMapping (fiWebConfig.Directory.FullName, true );
                   fm.VirtualDirectories.Add(entry.Properties[
"AppRoot" ].Value.ToString(), mapping);
                   System.Configuration.
Configuration cfg = System.Web.Configuration. WebConfigurationManager .OpenMappedWebConfiguration(fm, entry.Properties[ "AppRoot" ].Value.ToString());
                  
foreach ( KeyValueConfigurationElement elmt in cfg.AppSettings.Settings)
                   {
                        items.Add(
new string [] { elmt.Key, elmt.Value });
                   }
                }
            }
            
return items;
       }



The method above will return a List of all in the web.config file (the appSettings section), you can easilly adjust it to fit your needs.

As you can see the magic begins in :

> System.Configuration. Configuration cfg = System.Web.Configuration. WebConfigurationManager .OpenMappedWebConfiguration(fm, entry.Properties[ "AppRoot" ].Value.ToString());


method. You simply need to make some preparations befor ask it to open the web.config.

Note : this code again is written in few minutes and does not pretend to be optimized, you can again use it at your own will.

Jan 17, 2008

Interesting Apple Ad

Recently I came across this link. It's amazing how creative the Apple marketing team is and how they exploit the Apple vs. MS war.

Have fun :)
.

Jan 13, 2008

How much does your site costs?

Recently I cam accross this site : http://www.smartpagerank.com. What impressed me was that this site can estimate (who knows how exactly) how much does your site costs.
Unfortunatelly my blog was estimated to 0$ but that's subject to change :P. I will also put this code into the left side of my site. You can check it out either.
>

Another 5 minutes with C# to post to Google Blogs (Blogger.com) using Google Blogs SDK (2)

I revised the tool a bit, here is how it looks now:





Also I made some refactoring to the code and it looks better now (no more richTextBox1 names ;).
I plan to release this tool in order to help developers blog code to their blogger accounts easier. The next secret I am going to reveal is that I started a toolkit to help you create blog related programs with C# / .NET / Google Blogs API.

For now I am planning to release the program for free, as a Lite version and I plan to spend some more time to create a better looking version with SEO features in it and distribute it for a small fee (something like 10 EU).
The Toolkit will released for free now.

Well that's it. I am looking forward when I will have some more time to develop those
controls and programs to help the Blogger community grow ;)

Jan 10, 2008

5 minutes with C# - Get your blog in TreeView Control

I played a bit more with the Google Blogs Api and was able to create a custom TreeView control to help you get your blog in Hierarchical View.

Here is a screenshot of the TreeView:



The control will be soon released to my site and new blog post will be published to let you know
.

Another 5 minutes with C# to post to Google Blogs (Blogger.com) using Google Blogs SDK

             // Create service to be used for queries
             Service service = new Service ( "blogger" , "blogger-sample" );
            
AtomEntry createdEntry = new AtomEntry ();
            
// Create credentials you should add your blog username
             // and password here
            service.Credentials = new GDataCredentials ( "your_username" , "your_password" );

            
// As I only have one blog to speed up - I am taking it,
             // You can extend here in order to allow the user to
             // select from mutliple
blogs if he / she has.
             Uri firstBlogUri = GetFirstBlogUri(service);
            
            
// If we have the Uri - it's time to actually post.
             if (firstBlogUri != null )
            {
               
// Create FeedQuery and assign Uri.
                FeedQuery query = new FeedQuery ();
                query.Uri = firstBlogUri;

               
// Create Atom Feed from that query.
                AtomFeed feed = service.Query(query);

               
// Create atom entry for the new post
                AtomEntry newPost = new AtomEntry ();

               
// Fill in the post information
                // You need to have a control named richTextBox2 which will
                // contain the post body and a textBox1 control which will
                // contain the post title.

                newPost.Title.Text = this .textBox1.Text;
                newPost.Content =
new AtomContent ();
                newPost.Content.Content = richTextBox2.Text;
                newPost.Content.Type =
"html" ;
                newPost.Authors.Add(
new AtomPerson ());
                newPost.Authors[0].Name =
"Pavel Donchev" ;

               
// Try to publish and report success / fail:
                try
                {
                   createdEntry = service.Insert(query.Uri, newPost);
                }
               
catch ( Exception ex)
                {
                  
MessageBox .Show(ex.Message);
                }
               
if (createdEntry != null )
                {
                  
MessageBox .Show(newPost.Title.Text + " posted successfully!" );
                }
            }

There is also a helper function to retrieve the blog Uri:

      
Uri GetFirstBlogUri( Service service)
       {
            
FeedQuery query = new FeedQuery ();
            
// Retrieving a list of blogs
            query.Uri = new Uri ( "http://www.blogger.com/feeds/default/blogs" );

            
AtomFeed feed = null ;
            feed = service.Query(query);
            
AtomEntry entry = feed.Entries[0];
            
for ( int i = 0; i < entry.Links.Count; i++)
            {
               
if (entry.Links[i].Rel.Equals( "http://schemas.google.com/g/2005#post" ))
                {
                  
return new Uri (entry.Links[i].HRef.ToString());
                }
            }
            
return null ;
       }

Jan 8, 2008

5 minutes C# code to help you blog source ...

As I was unabled to find a reliable editor to convert my code samples to html, I decided to write one. You need two richTextBox components, named richTextBox1 and richTextBox2 and a Button, named button1.

Here is the code you need to put into the button1 click event handler:
       private void button1_Click(object sender, EventArgs e)
       {
            
string oldColor = "-";
            
string newColor = string.Empty;

            
StringBuilder strHtml = new StringBuilder();

            
for (int i = 0; i < this.richTextBox1.Text.Length; i++)
            {
                richTextBox1.Select(i, 1);
               
newColor = System.Drawing.ColorTranslator.ToHtml(richTextBox1.SelectionColor);
               
if ((newColor != oldColor) && (newColor != string.Empty))
                {
                  
if (!oldColor.Equals("-"))
                   {
                        strHtml.Append(
"");
                   }
                   strHtml.Append(
" + newColor + ";\">");
                   oldColor = newColor;
                }
                strHtml.Append(richTextBox1.SelectedText.Replace(
"<", "<").Replace(">", ">"));
               
Application.DoEvents();
            }
            strHtml.Append(
""
);
            
StringBuilder sbNew = new StringBuilder();
            sbNew.Append(strHtml.ToString().Replace(
"   ", "   "));
            richTextBox2.AppendText(sbNew.ToString());
       }


PLEASE NOTE: this code was written in 5 or 10 minutes, it doesn't pretend to be either clean or readable, it simply works. If you want - you can take it, optimize it, use it or whatever, just have in mind it wasn't written carefully ;).

Dec 28, 2007

Get IIS sites and virtual directories with .NET / C# / Directory Services

       public List GetSites(string serverName)
       {
            List Nodes = new List();
            CustomTreeNode tnResult = new CustomTreeNode();
            try
            {
                DirectoryEntry w3svc = new DirectoryEntry("IIS://" + serverName + "/w3svc");
                foreach (DirectoryEntry entry in w3svc.Children)
                {
                   if (entry.SchemaClassName == "IIsWebServer")
                   {
                        CustomTreeNode Site = new CustomTreeNode(entry.Properties["ServerComment"].Value.ToString());
                        this.ServerLoadStart(entry.Properties["ServerComment"].Value.ToString());
/>                        Site.CurrentEntry = entry;
                        Site.ImageIndex = 1;
                        Site.SelectedImageIndex = 1;
                        Site = GetVirtualDirectories(entry, Site);
                        Site.ImageIndex = 0;
                        Site.SelectedImageIndex = 0;
                        Nodes.Add(Site);
                   }
                }
            }
            catch (Exception ex)
            {
                string msg = ex.Message;
            }
            return Nodes;
       }
       private CustomTreeNode GetVirtualDirectories(DirectoryEntry site, CustomTreeNode Parent)
       {
            string VirDirSchemaName = "IIsWebVirtualDir";
            DirectoryEntry folderRoot = site.Children.Find("Root", VirDirSchemaName);
            foreach (DirectoryEntry deChild in folderRoot.Children)
            {
                CustomTreeNode tnFolder = new CustomTreeNode(deChild.Name);
                this.VirtualDirectoryStart(deChild.Name);
                tnFolder.ImageIndex = 0;
                tnFolder.SelectedImageIndex = 0;
                tnFolder.CurrentEntry = deChild;
                tnFolder.ImageIndex = 1;
                tnFolder.SelectedImageIndex = 1;
                Parent.Nodes.Add(tnFolder);
            }
            return Parent;
       }

Here is the result I get after few more hours of work:


Aug 28, 2007

The silent catch

Another of my interesting phrases (or at least I don't know if someboddy used this phrase). What is silent catch?

Silent catch is a term I use for try .. catch block, where the catch does nothing or at least you don't see it to be doing anything.

The first example:
try
{
some unsafe code here ...
}
catch {}

Another example:
try
{
some unsafe code here ...
}
catch (Exception ex)
{
hide something (for example grid or some other control) ...
return;
}

The second example is as bad as the first. It will be underlined by the Microsoft Visual Studio code editor to warn you that the ex object isn't used anywhere within the body of the catch statement.

Today I spent about two hours to investigate why a page doesn't display
one Grid. It appeared to be beried deep inside the system (I mean it was in an ascx control). The problem appeared to be missing view in the database. Unfortunatelly after I couldn't see the exception I was forced to start from the web user interface, first I checked the settings in the application to see if it is not forbidden or something, then I started to debug, to see where this part of the page comes from. After I found it, I needed to see what's going on in the control. So it took me two hours to trace the problem. What if there were an exception with stack trace? 15 minutes of work would have been enough for me to see that the view is missing.

So:
"Try to avoid silent catch statements as they may cost you a lot of efforts to find the problem later (even if you wrote the code on your own)."

Aug 23, 2007

Settings, they are supposed to help ?!?

Yesterday I had a tricky problem. I client of our company complained he can't upload files on our system. I started troubleshooting the problem. Each time I clicked the "Continue" button exception was thrown as if an assembly can not be found. It was pain in the neck. The assembly was something like "System.Web.UI.MobileControls.Adapters" (I can't remember the exact name now but it doesn't matter as we didn't use that assembly at all). I asked a collegue of mine for help (thanks Vesko!). The problem was in Machine.config file so we decided to back it up and comment that provider to see what will happen. It threw an exception, but this time more reasonable. It said there is no disk space. I logged again onto the server to free some more space
and gues what? There were 60GB of free disk space! I started to think where the problem might be and tried to find solution in Google. It finally appeared that the problem is a setting within the OS. Short explanation below:
Windows 2003 Server uses NTFS file system. This file system is capable of maintaining disk quotas for each user. In other words - the administrator may define how much disk space each user can use. It was set to 1 GB for the user, running the service responsible for the upload. So I set it to 3 GB, tested to see if it works and it worked. Then I left the server and asked the administrator to decide how much disk space will be available to the user running the process.

After this space is used again I will know what to do ;).

So I learned very useful lesson - first check the settings and then try to debug or touch the code. In most cases if the code worked before and you know nothing has changed - this means that some resources available to the application before aren't available now OR someboddy changed some setting which was important for your code to run smoothly.

Aug 9, 2007

Surface Fixing



What is surface fixing?


Surface fixing is a phrase I use for a fix, which is implemented in a layer above the layer where it occurs. If we imagine the standart 3-tier architecture and we have a bug in the Data Access Layer, surface fix will be to implement the fix in the Business layer or the Presentation Layer. It is common for junior developers or companies where the things should happen in a matter of hours or days (companies with short deadlines).



Example of a surface fixing:





Let's say we have a page for registering users (Presentation Layer). On user registration this page creates the User object (Business Layer). Sets its properties as necessary, and calls it's Save() method. The Save() method creates

an instance of the UserDAL object (Data Access Layer) and decides whether the task is to create new user or update existing one. Let's say we will create new user. The User Business Object -> Save() method will probably call something like : UserDAL -> InsertUser(long UserID, string UserLogon ....);

Now let's say that the Data Access Layer doesn't escape the single apostrophe in the UserLogonID. Passing parameter as O'Conner or something like this causes exceptions. The question is where should this be fixed?

I see most of you answering : "In the Data Acess Layer offcourse!". That's the best place but if you are working on a small project.

Now ask yourself what will happen if we fix this in a big enterprise system with hundreds of modules / pages referring to that particular routine? After all the other modules / pages are working they will stop working or at least stop working correctly. With other words - your fix will require the whole system to be redeveloped. And what's worse - the QA team will have a lot of work. They will love you for sure :). And to make the things even worse we will imagine that we are near the deadline (which is almost sure after we are testing already). In such cases the Surface Fixing may help.

Below I am giving the advantages and disadvantages of the Surface Fixing.

Advantages:

  • Your fix will not broke anything in the existing modules
  • The fix will only be tested, not the modules which may be affected
  • Ideal to use near deadlines

  • Disadvantages:

  • The fix isn't applied at the right place
  • Conflicts may appear in the future with modules which are working correctly
  • Against the official software development standarts


  • When to use this approach ?

  • When we are developing module in a big system with lot's of other modules which depend on the bug
  • When we are near deadline
  • When we are sure that there will be new version.


  • Conclusion:

    This approach is perfect to fix some bugs in the current version, but consideration to completely fix it in the next versions should be made. It simply is not right to use this approach as a regular fixing guidance. In the software development and the 3 or more tier models the above layes should only see the previous and depend on it. And what's more important - the above layer should get the data as expected.

    Jul 8, 2007

    New company - new luck :)

    Yep, only in few hours I will be on my new desk in my new company :). I am very excitet about this. The new company is Vizibility and it is developing web modules. At first glance it seemed very very interesting with all the young people there. They were very hospitable on the interview and managed to earn my complete confidence. It seems that I did that too. After I met their requirements they met mine too.

    So it is a big day today :). Wish me luck
    !

    Jun 30, 2007

    Skype API (Skype4COM) + Google MAPS API = ? [3]

    As a part of my Google Maps and Skype API I wanted to add custom icons to represent different objects on the map (currently I made it for the bus stations).

    The picture bellow is the result :



    It was again easy - we simply create GIcon object. Then we assign the URL of the image to be used, size of the icon and point, where the info window will appear :


    Code


    icon = new GIcon();
    icon.image = 'BusFine.gif';
    icon.iconSize = new GSize(39, 60);
    icon.iconAnchor = new GPoint(5, 34);
    icon.infoWindowAnchor = new GPoint(5, 2);




    Then we only need to add this object as a second parameter in the GMarker object constructor.



    Code


    // point is a GPoint object, representing the location the marker
    should be
    // displayed.
    marker = new GMarker(point, icon);



    Note : Some browsers may need some more settings in order to display the custom icon correctly, the example above is for IE.

    Jun 18, 2007

    Skype API (Skype4COM) + Google MAPS API = ? [2]

    The last few days I played a bit more with this little thing and made it a bit more stable.  First of all there were some strange silver rectangles in the map (which I suspect is becouse I use IE) another struggle was to force the map not to resize (pretty strange, huh?). I solved both issues at once by adding overflow="hidden"  style attribute to the div, containing the map. It is quite strange.  I also added the stnadard map types controls (Map, Satellite and Hybrid), that wasn't hard but took a lot of search in the net, I had the feeling that I need to define my layer, I don't know why but in the end I understood I only need to call : map.addControl(new GMapTypeControl()); it simply cannot be more easier. After the lesson with
    the map type control it was a line of code to add the large zoom control : map.addControl(new GLargeMapControl()); the guys from Google really rule the world :). They made it as easy as possible. After I got the map types and the zoom control I wanted some challenge. I decided to add a tabbed info window, only for the test the first tab I wanted was : "User Info" and I wanted the second to be "Date of birth" that was again as easy as possible ! Nice work, googlers !

    Finally here is what I have so far :


    I will try to add custom layers and lines these days only to test how it works and is it hard to implement.

    Jun 10, 2007

    What happened with the Data mining?

    Well, I simply stopped the project for a while, since I need to see the legal aspects of it. I am not quite sure if it is legal to simply take some catalogs from somewhere, reformat them and use them as your own. I think I can do such thing with some free public catalogs, but I will not act, until I have the written permission from the authors. Here are two screenshots of the spider in action :



    The above screenshot is when the spider is gathering data. It displays how much data is gathered and what the spider is doing in the given moment.



    The above screenshot displays the results of the crawl as a treeview. It uses MS Access database to store the data (since it is a small project).

    Technologies used for the spider :
    />.NET 1.1 (Windows Forms), MS Access, Internet Explorer Automation COM Libraries (AxWebBrowser, ShDocVW COM mshtml).

    Training your collegues from the beginning

    A collegue of mine recently wrote very interesting post about the relations at work (here). He is currently project manager but he was also software developer for years. So he knows a lot about those specific problems at work. I think I also can give my opinion on the subject as a intermediate software developer.

    Some problems:

    First of all - it is really hard to refocus after being taken away from your work once. That's true. It is also true that some time a single line of code somewhere deep in the project once found may be lost easilly, which means more hours of work. I think that in our work we should first respect each other. So if I respect my collegues I will not ask them to come to my desk each five minutes. I will think on
    what exactly do I want to ask them, after they come and answer to me I will think what else can be difficult for me and ask that collegue who is already on my desk. It is really disturbing someone to ask you to come each five minutes to help him / her and to see that this person doesn't care what are you talking about. Or to hear - "I can't think now". Every time I hear this I know I will be asked to come back to that particular desk in not much than five minutes. So trying to extract knowledge and routine from other people's mistakes I have the following rule - if I can't think and see that I am absent-minded - I simply take few minutes and then I ask my collegue to help me. Also when I hear : "I'm not here." - I simply ask that collegue to have few minutes break and then ask me to help him/her. So rule number one is to estimate why is your collegue facing that particullar obstacle - is it so hard or he / she simply needs few minutes of break so he/she can focus. It doesn't make any sense to bounce between your desk and that of your collegue if he isn't there, right?
    On the other hand - ignoring any team member leads to disballance in the team. We should be as responsive as possible in order to push our projects ahead. But the trick is to make your collegue deal with the difficulty or at least remember the solution so he can use it next time. That is what actually upgrades us as software developers.
    Another very frequent problem is the psychological barrier. I had collegues who simply deny to try deal with the problem. For example I've heard : "I don't know JavaScript". And he/she simply stops his / her work when it requires JavaScript. In such cases I am trying to convince that buddy that this is very efficent and useful technology to point some advantages using it and to make it look easier. I am saying : "See, it's not that hard, you simply use this property and everything you needed is done."
    I believe when you go to another desk to help someone you should not only think about the problem itself but the condition the other party is in. So being helpful developer requires some kind of psychological knowledge.

    Senior software developers against juniors

    That often becomes a great problem. Some of the senior software developers simply can't teach the youngers on how to deal with their work. In most cases it happens becouse the seniors are too self-reliant. They often believe their work is ten times more important. In most cases it is true. But investing in future seniors is also very important. If you train junior developer well - he will become senior too and will help you with your work.

    Isolation at work

    There are people who doesn't seem to be a part of the team. At first the headphones- I think it is good to put headphones on your head so you can isolate from the noise for example. It is not right, however, to make them a wall between you and the team. You should be open to any team member. I also have headphones at work. They help me a lot to isolate myself, but I am also trying to watch if somebody is comming to my desk and I take them off in the moment I see him/her. If he/she is few meters away and see that you are taking off your headphones he understands that you are ready to help and what is even more - that you will be glad to help. It is a simple psychological stimulation. We should spend much time in thinking about those little stimulations which can improve the relations at work a lot.

    Other developers don't need headphones to build a wall between them and the team (or at least the younger part of the team). I think those should be punished somehow. The should also be responsive and help their collegues. I've worked with developers who answer to your question with half word, making you feel the most stupid developer on the earth. They say : "How can you missed this, it's so easy, I can't believe you ask me for this." Once you hear this answer you will not ask that developer for anything. What's even worse - you won't want to see him/her outside.

    Jun 9, 2007

    When to decouple?

    It is quite modern nowadays to decouple things. One project in USA to deal one business requirement, another in Pakistan to deal with some other business requirement and one more in Romania and one more in Bulgaria...

    Is it so good indeed to decouple single project into Web services and make them talk each other?

    Well I think as most things in this life decoupling has its advantages and disadvantages.

    I nearly lost my mental health becouse of an xslt to transform an xml document to another xml document so it can be sent from a system we are developing to a system, which provides document printing. Does it worth to write 14, 000 lines of xslt code only to print a document? Well, depends on the viewpoint. First of all decoupling minimizes
    the development efforts in the corporation, by splitting it into development efforts in two or more corporations. That's good #1. Second - it can save years of gathering data (a good example are the credit providers in the USA, they have information you can hardly obtain other way but using their (paid) services). That's good #2.
    The support is done by the other party, you don't need to care about it. That's good #3.
    The other good thing is that there's always someone else to blame for something not working ;). That's joke ofcourse. The truth is that if your code doesn't work - you'll lose your clients. That's the simple truth about any business.

    Now let's turn our attention on the disadvantages the SOA and decoupling may bring to you. The first and one of the biggest disadvantages is that YOU ARE DEPENDING ON SOMEONE ELSE. Any technical problem on their side will affect your side and what's worse - it will also affect your customers. And what is even worse- it will (in most cases) harm your reputation, not the reputation of the party that made the mistake (so be careful about what are you writing in the error messages the customer will see on other party fail;). Yeah, I mean it. You shouldn't accept the other party guilt as yours, if they could delivered it to you, you would have delivered it to the client, right? So instead of writing :
    "Error, we have a problem"
    write :
    "Error, our partner have a problem."
    Other big disadvantage is that while developing your side code you are facing a black box. You don't know what's happening in this black box and why it is responding in the way it does. You can only trust the documentation you may have. But is everything in it? No, I don't think so. Especially for complex services some small things are always missing and you need to either figure them out (which costs a lot of money for pills) or contact the other party and wait so they can clear the problem and document it.
    I remember once I faced great problems with a web service which simply refuses to return any response. Only some simple empty xml document. Finally we figured out with my colleagues it needed two spaces in the begining of the document. I remember I wanted to swim from Bulgaria to USA to ask the guys who developed this thing to show me how would the request the document. The development dificulties, however are not a great obstacle, becouse once passed, they won't worry you anymore. But there is one more disadvantage which will remain - the transportation of the data. In order to get response from a third party service you need to send it request (this request is transported over the Internet), the service needs time to process it and then it returns you the request (which is also transported over the Internet). Then you may do something with this request and send response to the client (which is also done over the Internet). So instead one response / request pairs, you will have two. That's 100% bandwidth growth. It isn't something you can live with.

    So the question remains. When should we use decoupling and SOA (I mean services, provided by third parties)?

    I think it is a good choice to use third party services when you need some sort of information which is hard to obtain or may require too much time and which someone already have (credit reports in USA are good example, I think). You also may consider using SOA for services which will require a lot of time for development and which are already developed by third parties. For simple services - I think it is better to develope them on your own, so you don't waste too much bandwidth and depend on other parties.

    Skype API (Skype4COM) + Google MAPS API = ?

    I've played a bit last few days. I was interested in mixing the Skype4COM library (Official Skype API) with the Google Maps API (Google's Geocoding Service). It was quite tricky to make them both work properly, but finally I got some "results". Screenshots of the results will be published in this post the next few days, since I have some difficulties using the blogger upload utility (probably it is becouse my ISP, not blogger itself).









    And this is what I have done with Skype (Skype4COM) and Google Maps Api. I am thinking on how to incorporate this program into skype (probably as plugin or something) so it can be easier to use.

    >