TweetFollow Us on Twitter

Sep 01 Programming2

Volume Number: 17 (2001)
Issue Number: 09
Column Tag: Programming Philosophy

Mac vs. Unix traditions

by Marcelo Amarante Ferreira Gomes

How to combine the best of both with MacOS X without gathering the worst

A Big Move

With the advent of Mac OS X, Apple has departed from the traditional Mac OS system software to a new model, that of Unix. This has brought a great impact, both upon users and developers. In this article, I'll concentrate on the impact it has on us, developers.

Mac OS X brings a lot of changes. We now have a single filesystem tree, for instance, instead of a tree for each mounted volume; we have lots of users, instead of the few we had with Classic, even though most are fake, like root or bin; we have a much more complex concept of process ownership, with process groups, effective and real user and group IDs and a controlling tty. These - and lots of other - changes also change the way we code, something that even resembles the move from 68k to PPC in 1994, but is a lot closer to the move from System 6 to System 7 in the late 80's and early 90's.

There were no new things to think of when we moved from 68k to PPC, only lots of programming pitfalls. But when System 7 came up, later to be renamed Mac OS 7, we actually had to think different. Those readers old enough to remember will recall that when System 7 came up, we had to think of High-level events, mostly Apple events, for simple tasks like opening a document, and try to use them whenever possible, instead of the low-level events and Finder lists we were used to. We had to revamp our user interface, so that our applications wouldn't look displaced in that new and way cooler-looking GUI. We had also to do away, once and for all, with our 24-bit stuff and use 32-bit-clean pointers and handles, paying attention to the possibility of the use of virtual memory in the system.

For those of you new to Macintosh, but experienced Unix developers, there were a few similar moves that the Unix community has gone through, too. They have been much smoother, since there was no single company dictating directions to developers, like Apple does in the Mac arena. To name a few, there was the move from the single mainframe with lots of terminals to lots of networked personal workstations; from UUCP and serial-based WAN links to TCP/IP and Ethernet-based LANs; from character-based UI to X-based GUI; from single-computer passwd files to distributed NIS and/or shadow user databases. Some of these were actually additional options, rather than changes. For instance, I hardly recommend the use of NIS, even though I do recommend shadow password files. And even today, I still recommend UUCP links and character-based UI in specific cases. But either the new features or the changes in them required some extra care in the way one writes a new piece of software, and I'm not referring only to programming pitfalls here.

I could go on, naming other changes like these, both in the Mac and Unix fields, but the important thing here is to point out that there are some major moves in development scenarios from time to time. And when such a move brings lots of changes at once, it also produces changes in the programming philosophy. That's what's happening with the introduction of Mac OS X. And those of us who fail to perceive this will probably also fail to survive in a market that is always hungry for state-of-the-art technology.

What's A Programming Philosophy, Anyway?

It's not only about programming caveats. The programming philosophy encompasses the way we design, we use, and even think about the uses for a computer system. Most Macintosh users think of their computers almost as a friend, while Unix users tend to think of them only as a tool to get some job done.

Mac OS has traditionally been very user friendly and highly customizable but very consistent through different applications, both in terms of the interface with the user and the functionality. Unix, while highly customizable in functionality - even more than the Mac in most aspects - is usually very harsh with its fixed user interface. It seems to have been designed to work as a server, while the Mac OS is a great workstation.

Veteran developers always take these facts into account, even if unconsciously, and write code that corresponds to their perception of what the user needs. What Apple is doing now with Mac OS X is bringing the two worlds together, releasing an OS that is great for both a server machine and a workstation. This means that Apple wants users to have the same consistent user interface through all pieces of software they interact with, while having rock-solid system stability and compatibility.

Give Users What They Need

To build a successful Mac application, one must deliver what the user needs. Note that this does not mean that you should code just what the user expects. You can and should surprise the user with new and improved ways to do something. But try to invent features that users would guess when presented with a given screen. Developers with no previous Mac programming experience should observe mainly the Mac human interface guidelines. The typical Mac users expect every application to be similar to all others. They are used to reading the manual only as a last resort. Applications should be intuitive to them.

Apple has defined the recommended human interface guidelines required to achieve a successful Mac application long ago. These are constantly being improved, as new creative ways to interface with the users are developed, but the basic rules are always the same. What they say can be summarized as:

  • when you add a feature to your software, do it in a way that resembles something you've seen before in another software;
  • if the feature you're adding is radically new, try to imagine what the user would do to access that feature. Better yet, make a prototype of your application and have long-time Mac users play with it for some time. Pay attention to what they try to do, and listen to their comments very carefully.

There are lots of standard Mac OS interface elements that can be used to give users a clue to what they should do to get something done. If your particular feature does not fit into any interface elements, you should probably talk to a veteran Mac user about it. If you both decide there's no interface element that fits your needs, then try to invent your new element as similar as possible to another existing element. And always provide clear visual clues of the way your new element works.

Be Compatible - And International

In Mac OS, as well as in Unix, there are some conventions about where to put settings files, support code libraries, font files and lots of other things. Unlike in Unix, though, these special places should not be referred to by name. Apple has introduced the FindFolder system call a long while ago to give your software the path to these places. You can find the official Apple documentation on FindFolder at [1].

Under the Cocoa programming environment in Mac OS X, Apple thought you wouldn't need FindFolder, so they provided NSUserDefaults instead to store settings. See [2] for more info.

I see some of you asking: "why should I care about making a system call to find out what I already know?" This is a common pitfall. Settings files should go into the System Folder:Preferences folder, right? Not always. Under the Brazilian version of Mac OS, for instance, they should go into the Pasta do Sistema:Preferências folder. Besides, always making sure to call the proper system functions enables Apple to restructure the filesystem layout without breaking any software and without having to support two folder structures at the same time.

With software that don't call FindFolder, international users end up with some settings files in the correct place while some other software create folders with foreign names and store their preferences there. Try to explain that to a user!

A much worse situation comes up with installer software. Say you need to put a certain file in a special folder, like System Folder:Extensions in Mac OS Classic, or to alter one of the rc.* under the /etc in Mac OS X. If you don't make the appropriate system call, your file may end up in the wrong place, and your software simply won't work. Please note that I, as a novice Mac OS X programmer that we all but a few Apple engineers are, haven't been able to find what the call would be to find the proper /etc directory or the rc.* files. Maybe it doesn't even exist, in which case Apple should provide us with such call.

Don't Mess Things Up

The same "don't mess up with the filesystem" can be said to wannabe Unix developers. Developers with no previous Unix experience must take into account various aspects of the Unix culture, especially those that have security implications. Apple itself has made some significant departures from traditional Unix practice.

For instance, most, if not all, Unix variants have a real directory for /etc. With Mac OS X, Apple has decided to make /etc be a symbolic link to /private/etc. There are other systems that put a symbolic link where a real directory would be, most notably Solaris with its /bin being a link to /usr/bin, but generally there's a good reason for this kind of change.

I don't know what was Apple's reason for putting a symbolic link in the place of /etc. The only thing I can think of is to make it easier to change most of the system's configuration by just making the link point elsewhere.

But this kind of change is dangerous, given standard Unix programming practice and system call side effects. It must be done at a very carefully chosen time during the boot process. It could also be done while the system is up, but one should be aware of the implications of this huge change in his or her particular system.

One problem that could appear stems from the fact that when a process opens a file, it gets a file descriptor that refers to whatever has been named by the time the open system call has been made. After that call, it doesn't matter if that file is moved, renamed or even deleted: the file descriptor sticks with the originally opened file. In case of deletion, the disk space is freed only when all of the processes that have opened it have also closed it. With all this, if one ever changes the symbolic link in /etc, there is the risk that one process, for instance, a server started at boot time, has a configuration file open that doesn't correspond to the configuration seen by all other processes started after the link has been changed.

The extent of damage caused by such situation can range from nothing at all to a completely disastrous crash. Or, worse yet, it can pose a security threat, for instance, when a client process thinks that the server will do some sort of security check, while the server thinks that check to be the client's responsibility.

Don't Reinvent the Wheel

Another departure Apple has taken from standard Unix with its Mac OS X was the use of the little known pax archiving utility for its installer process. I would personally have gone with tar, but I wouldn't mind Apple to have chosen cpio instead, since these two are the formats that most (99.9 percent?) die-hard Unix fans prefer to distribute software in.

With the use of pax, Apple has introduced some serious security flaws in their installer process. I have read a great article about this issue, but regrettably, I can't seem to find the URL in my bookmarks. Anyway, the main concern in that article is that pax does not deal very nicely with permissions and ownership data about already existing directories and files. Even worse, if you change a directory for a symbolic link, pax may get confused and delete the link, replacing it with a real directory. If the link had been placed there in order to save disk space and have the tree below it stored in another disk partition or other physical disk, you will run into big trouble.

Pax seems to have been designed to create all of the directories and files that it is installing, and it's not very clever to leave things like they are when it finds something already in place. That way, whenever you install new software, you risk introducing security holes that have long been corrected.

Until Apple fixes this, either by using tar or cpio instead of pax, or by making pax a little smarter, we will have to double-check our systems every time we install something. The easiest way to do so seems to be by looking at the installer package, taking note of all of the files it adds, along with the directories they reside in, and checking for their correct ownership, permissions and file type (regular file, directory, symbolic link, device file, etc.) Obviously, this work would be much easier if you take some time to store all of this information before the installation takes place and make any needed corrections afterwards.

Summing it All Up

Lots of other aspects about good development habits could have been mentioned here, both under Unix and Mac OS, but a magazine article is just too short to even give a good coverage, let alone being complete. The examples given here serve only to give you an idea of what kind of downturns you might run into by not being aware of standard practice.

But they also serve to give you an idea of what a programming philosophy is. It's about the way developers think, and the "right" way of doing things. Everyone will have a different idea of what is the "right" way of doing something, but some basic ideas are generally agreed upon among developers from a given OS. These basic ideas are what is being referred to here as a programming philosophy.

How to Get There

Ok, we have to develop a new programming philosophy, that of Mac OS X, which should be a little different from Classic Mac OS and from Unix, but should not steer too far from either. But how do we get there? That depends on whether you are coming from Mac OS, from some sort of Unix or you are completely new to both. Either way, you've got to take a look at some web page from [3], especially [4].

Mac OS X for Classic Mac OS Developers

Of course Apple wouldn't succeed if they wanted us to rewrite all of our dependable code, that has cost us years of testing and debugging effort. But Apple can't stand still. So, they have provided us with three environments: Classic, Carbon and Cocoa. Ok, you've heard that before, so I'll skip to the important stuff.

Classic takes care of users. They won't have to buy new versions of all of their software title before moving on to X, but it's discontinued now, and it's not worth writing anything new for that environment. Cocoa, on the other hand, is the all-new innovative programming environment, in which all the good stuff is. Unfortunately for us who have invested on C, C++, Pascal or other languages, only Objective-C and Java APIs are available to work with it.

Then, there's Carbon. The environment for those coming from Classic Mac OS is definitely this one. Carbon is something in between Classic and Cocoa. It doesn't offer all the cool stuff that Cocoa offers, but it does offer most of it, including most of the coolest features we've been hearing about Mac OS X. It allows you to move your applications from the old Classic environment with little effort. Better yet, if you write for Carbon, your code may be able to run on Mac OS 9 and, depending on the set of system calls you choose, even on 8.x, by just having CarbonLib installed there. You can learn more about it in [5].

You can still think of files most the same way you did before, call most of your favorite system calls and think of the system mostly as if it really were the familiar Mac OS you've always known - for a while. It won't take long before you start cursing those most words in the previous sentence. You'll want to move on to Cocoa. Carbon is just a bridge to make that transition smoother.

And please try to stick to the rules. Learn the Aqua human interface guidelines (see [6]) and Quartz new API calls that are needed to implement some of Aqua look and feel (see [7] and [8].) Don't just use the same old ways of interfacing with the user. Some of the old methods, like custom MDEFs or WDEFs won't work, anyway.

Mac OS X for Unix Developers

By now, you already know that Cocoa is for you. Or isn't it? That depends on your previous knowledge of either Java or Objective-C or your willingness to learn a new programming language. If you already know any of these two languages, then look no further. You've got to go the Cocoa way, so read [9].

But if you are a seasoned C, C++, Pascal, Fortran, Basic, or something else programmer, you might want to give Carbon a try, at least for a while. Be warned, though, that you'll have a much harder time than your fellow Classic Mac OS programmers trying to go this way. While they already know most of the philosophy involved in writing good Mac OS software, you'll have to learn that from the beginning.

The Aqua API will be something new, and don't even think about writing an X-windows application. Most Mac OS X systems won't even have X-windows installed. But don't let that discourage you. The concepts involved are very similar. You still have a main() function calling an event loop and acting on events, just like on X-windows. Only the API will be new. Well, not only the API - you'll have to play by the Aqua rules. Read [6]; reread [6], then read it once again. Tired of reading? Read it backwards once more, just in case. It's never too much to stress how important the GUI rules are to keep Mac OS consistent.

"Damn, I could forget about all this GUI stuff and write a character-only app," I hear you saying. Ok, go ahead. But don't forget what your intended audience is. The average Mac OS user doesn't even know what a character-based UI is, let alone how to get to a command prompt. But if your audience is just a bunch of colleagues of yours and you do write a character-based application, please play by the traditional Unix rules, and try not to mess up with the System Folder or some other Mac OSisms brought over from Classic to Mac OS X.

Mac OS X for Newbies

If you've read the previous sections, you stand a good chance of already knowing which way to go. You don't know any programming language at all? Learn Java and/or Objective-C and go the Cocoa way. You already know some C and only want to know what this fruit-branded OS is about? Ok, try Carbon.

No matter what environment you choose to start working with, please, please, please! Follow the rules. All of them.

The Bottom Line

So, no matter what your background in some other OS is, if you don't have a good knowledge on both Unix and Mac OS standard practices, please reserve some time to learn about the culture on these systems. And don't try to save time on this! It will take lots of reading until you can say you're ready to write a successful application for Mac OS X. If at all possible, talking to veteran developers and users should take much of your time, too. But you will spend much more time, money and effort by going ahead coding, writing manuals, license agreements and other documentation, investing on marketing and distribution, only to find out that the users didn't like your software.

Worse than that, when many developers start coding without regard to standard practice, eventually some of them will come up with exceptionally good software that users will like and use although it doesn't follow standard practice. It may even happen with your title. But don't be happy with that.

When a significant number of software titles disregarding minimal guidelines start to gain acceptance, there will be nothing to call standard practice anymore. And Mac OS won't have the consistency it has today. Users will have a hard time figuring out how to use software; various titles will start being incompatible with one another. Then everything Apple and the Unix community across the globe have fought for and accomplished during many years will have been thrown away.

Apple fails to comply with traditional Unix practice in a few spots with dangerous consequences, but those trouble spots are simple to fix. They seem to be doing an overall good job and moving in the right direction. Let's hope that all - or at least most - of us will also get this right, and let's make Mac OS X a success by combining the best of Classic Mac OS with the best that Unix has to offer. And let's not pour in the worst by accident.

Acknowledgements

I'd like to thank Jacques do Prado Brandão, my friendly neighbor who, even not knowing a thing about computers or operating systems, was always there to help me revise some grammatical glitches that stupid word processors can't, as well as keeping a straight line of thought throughout the whole article.

Someone else to mention is Sergio de Souza Prallon, a fellow Brazilian consultant who has read - and understood - this article in its entirety. Being a Unix-only guy, he came up with the idea of writing the entire How to Get There section. Then he lied to me and told me it was good. :-)

And I could never forget about Neil Ticktin, MacTech's publisher. He has told me that the ideas I have presented here could make up a good article, thus giving the spark that ignited this whole thing. Has it blown anything up?

References


Marcelo Amarante Ferreira Gomes is an independent Macintosh, Unix and Internet consultant. He works most of the time with his Brazilian partners, and plays most of the time with his kids and/or his Lombard Powerbook that has the single most important OS in the world, besides most other junk in this industry. You can reach him at suporte@mac.com... if you're lucky. :-)

 
AAPL
$99.02
Apple Inc.
+1.35
MSFT
$43.97
Microsoft Corpora
-0.53
GOOG
$590.60
Google Inc.
+1.58

MacTech Search:
Community Search:

Software Updates via MacUpdate

Acorn 4.4 - Bitmap image editor. (Demo)
Acorn is a new image editor built with one goal in mind - simplicity. Fast, easy, and fluid, Acorn provides the options you'll need without any overhead. Acorn feels right, and won't drain your bank... Read more
Bartender 1.2.20 - Organize your menu ba...
Bartender lets you organize your menu bar apps. Features: Lets you tidy your menu bar apps how you want. See your menu bar apps when you want. Hide the apps you need to run, but do not need to... Read more
TotalFinder 1.6.2 - Adds tabs, hotkeys,...
TotalFinder is a universally acclaimed navigational companion for your Mac. Enhance your Mac's Finder with features so smart and convenient, you won't believe you ever lived without them. Tab-based... Read more
Vienna 3.0.0 RC 2 :be5265e: - RSS and At...
Vienna is a freeware and Open-Source RSS/Atom newsreader with article storage and management via a SQLite database, written in Objective-C and Cocoa, for the OS X operating system. It provides... Read more
VLC Media Player 2.1.5 - Popular multime...
VLC Media Player is a highly portable multimedia player for various audio and video formats (MPEG-1, MPEG-2, MPEG-4, DivX, MP3, OGG, ...) as well as DVDs, VCDs, and various streaming protocols. It... Read more
Default Folder X 4.6.7 - Enhances Open a...
Default Folder X attaches a toolbar to the right side of the Open and Save dialogs in any OS X-native application. The toolbar gives you fast access to various folders and commands. You just click... Read more
TinkerTool 5.3 - Expanded preference set...
TinkerTool is an application that gives you access to additional preference settings Apple has built into Mac OS X. This allows to activate hidden features in the operating system and in some of the... Read more
Audio Hijack Pro 2.11.0 - Record and enh...
Audio Hijack Pro drastically changes the way you use audio on your computer, giving you the freedom to listen to audio when you want and how you want. Record and enhance any audio with Audio Hijack... Read more
Intermission 1.1.1 - Pause and rewind li...
Intermission allows you to pause and rewind live audio from any application on your Mac. Intermission will buffer up to 3 hours of audio, allowing users to skip through any assortment of audio... Read more
Autopano Giga 3.6 - Stitch multiple imag...
Autopano Giga allows you to stitch 2, 20, or 2,000 images. Version 3.0 integrates impressive new features that will definitely make you adopt Autopano Pro or Autopano Giga: Choose between 9... Read more

Latest Forum Discussions

See All

Traps n’ Gemstones Review
Traps n’ Gemstones Review By Campbell Bird on July 28th, 2014 Our Rating: :: CASTLEVANIA JONESUniversal App - Designed for iPhone and iPad Fight mummies, dig tunnels, and ride a runaway minecart to discover ancient secrets in this... | Read more »
The Phantom PI Mission Apparition Review
The Phantom PI Mission Apparition Review By Jordan Minor on July 28th, 2014 Our Rating: :: GHOSTS BUSTEDUniversal App - Designed for iPhone and iPad The Phantom PI is an exceedingly clever and well-crafted adventure game.   | Read more »
More Stubies Are Coming Your Way in a Ne...
More Stubies Are Coming Your Way in a New Update Posted by Jessica Fisher on July 28th, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
The Great Prank War Review
The Great Prank War Review By Nadia Oxford on July 28th, 2014 Our Rating: :: PRANKING IS SERIOUS BUSINESSUniversal App - Designed for iPhone and iPad Though short, The Great Prank War offers an interesting and fun mix of action and... | Read more »
Marvel Contest of Champions Announced at...
Marvel Contest of Champions Announced at Comic-Con Posted by Jennifer Allen on July 28th, 2014 [ permalink ] Announced over the weekend at San Diego Comic-Con was the fairly exciting looking Marvel Contest of Champions. | Read more »
Teenage Mutant Ninja Turtles Review
Teenage Mutant Ninja Turtles Review By Jennifer Allen on July 28th, 2014 Our Rating: :: DULL SWIPINGUniversal App - Designed for iPhone and iPad The pizza power is weak when it comes to this Teenage Mutant Ninja Turtles game.   | Read more »
Exploration Focused Puzzle Game Beatbudd...
Exploration Focused Puzzle Game Beatbuddy Set to Make Transition from PC to iOS this September Posted by Jennifer Allen on July 28th, 2014 [ permalink ] | Read more »
PlanetHD
PlanetHD By Nadia Oxford on July 28th, 2014 Our Rating: :: SPACE MADNESSUniversal App - Designed for iPhone and iPad PlanetHD will keep players busy for a while, though its unpredictable physics are a handful to deal with.   | Read more »
This Week at 148Apps: July 21-25, 2014
Another Week of Expert App Reviews   At 148Apps, we help you sort through the great ocean of apps to find the ones we think you’ll like and the ones you’ll need. Our top picks become Editor’s Choice, our stamp of approval for apps with that little... | Read more »
Reddme for iPhone - The Reddit Client (...
Reddme for iPhone - The Reddit Client 1.0 Device: iOS iPhone Category: News Price: $.99, Version: 1.0 (iTunes) Description: Reddme for iPhone is an iOS 7-optimized Reddit client that offers a refreshing new way to experience Reddit... | Read more »

Price Scanner via MacPrices.net

13-inch 2.5GHz MacBook Pro on sale for $1099,...
Best Buy has the 13″ 2.5GHz MacBook Pro available for $1099.99 on their online store. Choose free shipping or free instant local store pickup (if available). Their price is $100 off MSRP. Price is... Read more
Roundup of Apple refurbished MacBook Pros, th...
The Apple Store has Apple Certified Refurbished 13″ and 15″ MacBook Pros available for up to $400 off the cost of new models. Apple’s one-year warranty is standard, and shipping is free. Their prices... Read more
Record Mac Shipments In Q2/14 Confound Analys...
A Seeking Alpha Trefis commentary notes that Apple’s fiscal Q3 2014 results released July 22, beat market predictions on earnings, although revenues were slightly lower than anticipated. Apple’s Mac’... Read more
Intel To Launch Core M Silicon For Use In Not...
Digitimes’ Monica Chen and Joseph Tsai, report that Intel will launch 14nm-based Core M series processors specifically for use in fanless notebook/tablet 2-in-1 models in Q4 2014, with many models to... Read more
Apple’s 2014 Back to School promotion: $100 g...
 Apple’s 2014 Back to School promotion includes a free $100 App Store Gift Card with the purchase of any new Mac (Mac mini excluded), or a $50 Gift Card with the purchase of an iPad or iPhone,... Read more
iMacs on sale for $150 off MSRP, $250 off for...
Best Buy has iMacs on sale for up to $160 off MSRP for a limited time. Choose free home shipping or free instant local store pickup (if available). Prices are valid for online orders only, in-store... Read more
Mac minis on sale for $100 off MSRP, starting...
Best Buy has Mac minis on sale for $100 off MSRP. Choose free shipping or free instant local store pickup. Prices are for online orders only, in-store prices may vary: 2.5GHz Mac mini: $499.99 2.3GHz... Read more
Global Tablet Market Grows 11% in Q2/14 Notwi...
Worldwide tablet sales grew 11.0 percent year over year in the second quarter of 2014, with shipments reaching 49.3 million units according to preliminary data from the International Data Corporation... Read more
New iPhone 6 Models to Have Staggered Release...
Digitimes’ Cage Chao and Steve Shen report that according to unnamed sources in Apple’s upstream iPhone supply chain, the new 5.5-inch iPhone will be released several months later than the new 4.7-... Read more
New iOS App Helps People Feel Good About thei...
Mobile shoppers looking for big savings at their favorite stores can turn to the Goodshop app, a new iOS app with the latest coupons and deals at more than 5,000 online stores. In addition to being a... Read more

Jobs Board

*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
Sr. Product Leader, *Apple* Store Apps - Ap...
**Job Summary** Imagine what you could do here. At Apple , great ideas have a way of becoming great products, services, and customer experiences very quickly. Bring Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
WW Sales Program Manager, *Apple* Online St...
**Job Summary** Imagine what you could do here. At Apple , great ideas have a way of becoming great products, services, and customer experiences very quickly. Bring Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.