Enterprise Ajax - Transcend the Hype September 2006 Stephen Maryka CTO ICEsoft Technologies Inc.
May 18, 2015
Enterprise Ajax - Transcend the Hype
September 2006
Stephen Maryka
CTO
ICEsoft Technologies Inc.
© 2006 ICEsoft Technologies Inc. 2
Download ICEfaces
http://www.icesoft.com/downloads/
Ajax and the Hype Cycle
It's official - Ajax is all the rage, and why shouldn't it be? The pioneers of the Ajax World have taken
tremendous strides toward proving that Ajax techniques can deliver true benefits to web application users
through a richer interaction model than standard web applications can provide. The vacuum of Ajax
development technologies is rapidly being filled as startups and open source initiatives are being sucked out of
garages and basements everywhere. It seems that Ajax will be ubiquitous on the Web in no time flat.
Now back to reality and a little curve that the Gartner Group drew in 1995 to illustrate the Hype Cycle
associated with new technology adoption. That curve, as illustrated in Figure 1 below, has proven to be
accurate time and again over the course of history in computation, and will undoubtedly hold true in relation to
Ajax technologies. In fact, Gartner recently released their 2006 Technology Hype Curve, and Ajax is front and
center in their analysis (see: http://www.gartner.com/it/page.jsp?id=495475)1.
Figure 1: The Technology Hype Cycle
So where is Ajax on this hype curve? It is hard to pinpoint exactly, but according to the Gartner analysis for
2006, it is coming off the peak of inflated expectations, and we all know what comes next – the trough of
disillusionment. Furthermore, they expect that the trough could be as much as two years wide. With the high
visibility that Ajax has in the industry right now, expectations that Ajax-related benefits can be realized in the
enterprise are growing rapidly, and Gartner concurs, suggesting that the incremental benefits that Ajax can
bring are worth pursuing. So how does the enterprise developer effectively incorporate Ajax techniques into
their well-entrenched enterprise application development infrastructure today, and avoid the dreaded trough
along the way?
This paper examines various levels of Ajax development that the enterprise developer might entertain, and
explores some of the pitfalls that will be encountered along the way. It goes on to describe key concepts
© 2006 ICEsoft Technologies Inc. 3
Download ICEfaces
http://www.icesoft.com/downloads/
around Thin Client Ajax, and shows how ICEsoft's ICEfaces™ technology can position
enterprise developers to deliver rich Ajax features in their applications today. We then go
beyond the basics and establish a new level of Ajax development, one where dynamic content can be pushed
to the client presentation in a server-initiated manner, enabling a whole new level of dynamics to the
application. Finally, we show how these capabilities can be added incrementally to existing JSP applications,
enabling you to add a rich pallet of Ajax-enabled features to your legacy applications without a major
refactoring of your existing application infrastructure.
Levels of Ajax
Once you entertain adding Ajax-based features to existing enterprise applications, you will be faced with a
myriad of decisions. At the root of this decision tree is the need to identify the level of Ajax development that is
appropriate to meet end user expectations. In a recent article in ADT Magazine, Gartner analyst Ray Valdes
described four levels of Ajax development (see: http://www.adtmag.com/article.aspx?id=17953)2
summarized below:
1. Snippet: At this level, you add bits of JavaScript to an existing application to achieve minor client-side
behavior without re-architecting the application. Basic client-side validation of user input fields is an
example of snippet-level Ajax.
2. Widget: At this level, basic browser UI controls are augmented with Ajax-enabled controls that incorporate
more interactive features. Examples of Ajax-enabled controls include menus, pop-up panels, trees, etc.
Again, widget-level development can be achieved without significant re-architecting of the application, but
interactive features are confined on a widget-by-widget basis.
3. Framework: At this level, a JavaScript framework provides features beyond a set of widgets for
developing the UI in a client-centric manner. The framework provides basic infrastructure that supports
greater interaction between widgets. For example, the framework might provide an event API where
widgets can register to receive information from other widgets, and react to changing states within the UI.
Valdes claims that this level of Ajax requires a significant re-architecting of the application, essentially a
compete rewrite.
4. Enhanced Framework: At this level, the client-side framework is augmented with a server-side
framework to deliver an end-to-end solution. This is the first level that addresses server-side requirements,
but leads to fragmentation of the application where the data model is server-resident, but the UI business
logic is client-resident. It suffers from the same re-architecting issues that the framework level does, but
does not leave server-side integration entirely as an exercise for the developer.
Once you have absorbed the basic levels of Ajax development that you could entertain, you will likely feel under
whelmed with your options. Maybe in the short-term, snippet or widget level will do, but the reality is your
existing enterprise applications are server-centric, and anything short of an enhanced framework will prove to
be shortsighted. After all, server-side integration is unavoidable, so why attempt to build it from scratch. But re-
architecting your entire application, rewriting your UI in a client-centric manner, and dealing with the
complexities of distributed fragmentation of the application seem like non-starters.
So you stand atop the peak of the Ajax hype curve staring straight down into the trough of disillusionment. A
little Ajax is not enough, but a lot of Ajax seems undoable. Well, if you currently live in the Java Enterprise
world, there is a way to jump the trough, and it starts with a framework.
© 2006 ICEsoft Technologies Inc. 4
Download ICEfaces
http://www.icesoft.com/downloads/
A Framework Yes, But Where?
When we think of Ajax-enabled applications, we naturally approach them from a client-centric perspective —
after all, the enabling technology, JavaScript, is client-centric. But for the Java Enterprise developer, this
perspective is completely inverted. Most likely there is extensive back-end infrastructure that any Ajax-enabled
application will depend on, so the server-side integration described for the level-four Enhanced Framework is a
natural starting point, and should be the first consideration, not the last. You definitely want to leverage existing
infrastructure, developer core-competencies (Java), development environments, and best practices. So we are
motivated to preserve our server-resident data model and related business logic, but upgrade the presentation
layer with Ajax-enabled features. The four levels of Ajax development described above would lead you to
believe the only way to do this is to introduce a client-resident framework, reinvent your entire presentation
layer, and stitch it together with your existing server-resident infrastructure.
The moment that you entertain a client-side framework, you expose yourself to a world of hurt and seat-of-
your-pants slide into the trough. Briefly, some of the problems you will face include:
1. JavaScript Idiosyncrasies: Plain and simple, JavaScript behaves differently in different browsers. If you
build client-side presentation logic, you will be exposed to this issue. Some Ajax frameworks will shelter you
from this problem a bit, but don't be fooled. Extensive JavaScript development will be required, and your
matrix of pain will increase four fold if you want to support all popular browsers being used today.
2. JavaScript Development Tools and Best Practices: Or lack there of. Ajax programming is still in its
infancy, and the tools story is pretty dismal today. JavaScript debugging is most painful, and that pain is
magnified by the need to debug across multiple browsers, none of which provide necessary debugging
facilities to do an effective job. And just when you think you have something working across browsers, you
will discover a nasty memory leak somewhere in one of the browser implementations. Good luck with that
one.
3. Development Team Core Competencies: Your team is made up of mostly Java developers. Sure,
some of your engineers may aspire to becoming JavaScript hacks, but how realistic is it to shift away from
the core competencies of your team? The lack of tools and best practices will definitely impede your crawl
up the JavaScript learning curve.
4. Application Fragmentation: This is the big one. If you look beyond basic widget-level Ajax, it becomes
necessary to build presentation business logic in JavaScript for client-side execution. This means that you
must separate the presentation layer business logic from the data layer business logic, distribute them
between client and server, and stitch the thing back together somehow. In essence you need to take your
existing server-side MVC architecture (Figure 2), tear chunks out of it, re-implement them in JavaScript,
and stick it all back together in some sort of distributed MVC architecture, as illustrated in Figure 3. We all
know that distributed systems can be an order of magnitude more complex to develop and maintain, so
you will have a daunting task before you. And there is no effective way to achieve this re-architecting
incrementally, so you will have to bite off the whole chunk at once, and won’t have anything to show for
your efforts until you get it all working.
© 2006 ICEsoft Technologies Inc. 5
Download ICEfaces
http://www.icesoft.com/downloads/
Figure 2: Server-side MVC Architecture
Figure 3: Migration to Enhanced Ajax Framework Architecture – Distributed MVC
So if we discard the idea of using a client-resident framework for adding Ajax, and stick to our guns regarding
preservation of server-resident infrastructure, what are we left with? Let's turn our attention to JavaServer
Faces (JSF), and examine the possibilities. JSF is a component-based presentation layer framework for Java
Enterprise. On its own, JSF does nothing to deliver Ajax features, but because the component architecture is
extensible, one could imaging creating a suite of Ajax-enabled components, and building JSF applications that
exhibit Ajax characteristics. In fact, you will find several commercial and open-source component suites that, to
a greater or less extent, do just that. Figure 4 below, illustrates an Ajax-enabled, JSF-based application
architecture.
© 2006 ICEsoft Technologies Inc. 6
Download ICEfaces
http://www.icesoft.com/downloads/
Figure 4: Ajax-enabled JSF Application Architecture
For the Java Enterprise developer, this approach solves several problems:
1. Preserves back-end server-resident infrastructure.
2. Eliminates the need for extensive JavaScript programming.
3. Preserves developer core competencies, development practices, and tools.
4. Eliminates application fragmentation.
Furthermore, a JSF approach fosters incremental upgrade to an existing JSP-based application. It is not
necessary to completely re-implement the entire application in JSF. It is perfectly reasonable to systematically
replace pieces of the application with Ajax-enabled JSF, but preserve the overall JSP structure of the
application. In this manner, high-priority features can be delivered in a timely fashion, and the application can
be evolved over time into an increasingly rich, Ajax-enabled application. More on this topic later, but at this
point it would seem that Ajax-enabled JSF represents a viable approach to adding Ajax features to legacy JSP-
based applications. There are, however, limitations to this approach, and they stem from the widget-level
nature of the solution.
The Trouble with Widgets
In the levels of Ajax discussion, the notion of widget-level Ajax was introduced at level two, but the reality is
widget-level characteristics are prevalent in higher levels of Ajax development as well. For the sake of this
discussion, we loosely define a widget as a collection of one or more browser controls integrated together in a
fashion that enables some specific UI element that can exist in a browser page. A widget can be as simple as a
button or text field, or more complex like a tree or menu. Now, if a widget is Ajax-enabled that typically means
a couple of things:
1. The widget provides interactive features the user can invoke. Expanding and collapsing nodes in a tree is
an example of this type of Ajax-enablement. The interactive features are implemented using JavaScript to
© 2006 ICEsoft Technologies Inc. 7
Download ICEfaces
http://www.icesoft.com/downloads/
process user interaction events and manipulate the presentation of the widget
based on those user interactions. This is essentially DHTML.
2. The widget's presentation is bound to some server-resident data, which is dynamically retrieved using
JavaScript, and specifically the XMLHttpRequest. For instance, the precise structure of a tree and all its
branches could be retrieved automatically from the server based on some user interaction with the
application. Essentially, some portion of the widget’s data model is remotely maintained at the server, and
is accessed via JavaScript on the client.
In both instances, the widget's presentation will be updated autonomously from other presentation elements in
the page. Each widget exists in its own little silo of interactivity, as illustrated in Figure 5 below.
Figure 5: Widget-level Ajax
So, what happens if your business logic requires interactions to occur between widgets in the page? If you want
this to happen in an Ajax-like fashion, you either need to build a new widget with additional JavaScript that
supports the additional interactive features, or you need to wire the two widgets together with additional
JavaScript in the page. Essentially both these options represent the same exercise, and as you build more
sophisticated applications, with additional page-level interactions, it all leads to one thing—JavaScript
proliferation. But wait, haven't we already decided that we were going to try and avoid writing all that
JavaScript in the first place?
In reality, how complex can this JavaScript wiring be? We turn to another on-line publication to illustrate the
complexities you might face trying to wire widgets together in JavaScript. “Ajax In Action”, a Manning
publication, is one of the pioneer Ajax publications, and luckily for us the publisher has provided a couple of
chapters on-line. We refer you to Chapter 9 of this book - “Dynamic double combo” (available at:
http://www.manning-source.com/books/crane)3. This chapter describes how to build an Ajax-based double
combo box using JavaScript, and is a perfect example of achieving inter-widget interaction. The double combo
box is pretty basic, providing two select-one-of-many widgets where the selection in the first widget causes the
second select-one-of-many widget to adjust its content, as illustrated in Figure 6 below.
© 2006 ICEsoft Technologies Inc. 8
Download ICEfaces
http://www.icesoft.com/downloads/
Figure 6: Dynamic Double Combo Widget
Now if you skim through this chapter of the book, you will discover that a pretty simple inter-widget wiring job
only takes about 16 pages to describe. And if you want subtly different features from the combined widget,
well, there are another 18 pages of description for that. This seems pretty complicated for such a simple
example. Imagine if your application requires a myriad of inter-widget interactions in the page. You are
undoubtedly going to be exposed to a significant amount of JavaScript wiring to achieve it.
Beyond Widgets – Thin Client Ajax
Our little journey into widget-based development makes it pretty clear that as you add sophistication to the
application through additional inter-widget interactions, your task becomes more and more onerous. You find
yourself dragged down into low-level Ajax interactions, and are directly exposed to JavaScript idiosyncrasies.
Your primary objective is to add rich interactive features to the application, but you are distracted from this
objective as you sort out low-level issues with your Ajax technology of choice, and struggle with significant
architecture changes at the same time. What you really want to do is focus on the application, and have all that
Ajax stuff happen transparently—Thin Client Ajax, if you will.
So what might Thin Client Ajax look like? Imagine an architecture where the core MVC model remained server-
resident, and a standard application lifecycle generated new presentation as the state of the application
changed. Imagine that the presentation changes were incrementally communicated to the client browser, and
those presentation changes were assembled with only minimal re-rendering of the page. Imagine that user
interactions with the presentation were automatically communicated back to the application, where server-
resident business logic could react intelligently to the user and adjust the presentation accordingly. And to
complete the circle, imagine that the resulting presentation changes, no matter how pervasive or subtle they
might be, where again incrementally communicated to the browser and reassembled. Now, that would be Thin
Client Ajax, and the general concept is illustrated in Figure 7 below.
Figure 7: Thin Client Ajax
© 2006 ICEsoft Technologies Inc. 9
Download ICEfaces
http://www.icesoft.com/downloads/
With that picture in mind, now imagine being able to leverage pure Java, and existing
Java Enterprise standards, tools, and best practices to develop your application.
Furthermore, imagine that all this could be achieved without writing a single line of JavaScript. Now that is
ICEfaces, and it is the only Ajax technology in existence that delivers all the rich features of Thin Client Ajax
today.
ICEfaces – Enterprise-strength, Thin Client Ajax
So how exactly does ICEfaces deliver Thin Client Ajax? First of all, ICEfaces extends JSF, and as such is a Java
EE standards-compliant technology. There are a few key innovations in ICEfaces that enable the JSF framework
to deliver Thin Client Ajax.
1. Direct-to-DOM Rendering: D2D rendering is a technique that does just what it says. It allows a JSF
render cycle to render the JSF component tree directly into a server-resident DOM. ICEfaces provides a
complete component suite that is D2D-enabled.
2. Incremental Browser DOM Update: D2D rendering results in a DOM that represents the new state of
the presentation. If you represent the new DOM as a set of incremental changes to the old DOM, and have
a mechanism to reassemble those DOM changes in the browser presentation, you have the ability to
seamlessly update user presentation with minimal re-rendering of the page. In ICEfaces, this is achieved
via a lightweight Ajax bridge, which communicates incremental DOM changes using the server-resident
part of the bridge and reassembles those changes in the browser DOM using the client-resident part of the
bridge. It is important to note that client-resident JavaScript bridge code is a fixed size, and does not suffer
from JavaScript proliferation as page complexity increases.
3. Automated Partial Submit: ICEfaces components carry partial submit attributes that allow the
developer to configure them to cause an automated submit back to the server-resident application based
on user interaction with the component. Standard JavaScript events, such as on-blur, can be used to
trigger the partial submit and the Ajax bridge code handles all of the communication back to the server.
This technique enables finer granularity interaction with the user, and allows the application business logic
to react promptly and intelligently to the user with updated presentation. The whole mechanism is under
developer control, so the granularity of user interactions can be adjusted based on application-specific
requirements.
The process of D2D rendering with incremental page update is illustrated in Figure 8 below with the following
sequence of events:
1. User interaction with the presentation in the browser causes an automated partial submit over the bridge.
2. The submission causes the JSF application lifecycle to execute; the application business logic reacts to the
user interaction and produces some state change in the application.
3. The render cycle executes and D2D rendering results in a new presentation DOM.
4. The incremental DOM changes are returned to the browser via the Ajax Bridge.
5. The incremental changes are re-assembled in the browser DOM, and the presentation changes.
© 2006 ICEsoft Technologies Inc. 10
Download ICEfaces
http://www.icesoft.com/downloads/
Figure 8: D2D Rendering with Incremental Page Update
So there you have it—full-fledged, Thin Client Ajax. With ICEfaces, you get it by writing pure Java applications,
without a single line of JavaScript development. But wait, the story gets even stronger.
Push-style Applications – A Natural Feature of D2D Rendering
In Figure 8, we described a user-initiated application cycle, which is how all web-based applications work. But
what if the application data model is dynamic in nature? Is there any way that presentation changes can be
pushed to the client instantaneously when the state change occurs? You might entertain some kind of feeble
client-resident polling mechanism, but with ICEfaces you get true push-style capabilities with Ajax Push
technology, and you get it in pure, server-resident Java.
The D2D rendering mechanism delivers push-style capabilities in a natural way, and here is how it works. The
JSF lifecycle normally runs as a result of some user interaction with the application, but what if the server-
resident application could use some trigger mechanism to cause the render cycle to execute on demand?
Application state changes could trigger the render cycle, and the D2D mechanism would cause the presentation
to update in a smooth and seamless manner. That is exactly what ICEfaces does, and Figure 9: below
illustrates this with the following sequence of events:
1. The Ajax Bridge kicks off the process with an asynchronous update request.
2. Some state change in the application is detected.
3. The state change triggers a server-initiated render cycle, which produces an updated DOM.
4. Incremental DOM updates are assembled and the outstanding request is satisfied with the response.
5. A new asynchronous request is generated from the Ajax Bridge in anticipation of some future update.
6. The incremental changes are reassembled in the browser DOM.
© 2006 ICEsoft Technologies Inc. 11
Download ICEfaces
http://www.icesoft.com/downloads/
Figure 9: Server-initiated D2D Rendering
Ajax Push technology completes the picture for Thin Client Ajax. You now have an environment where
application business logic can react instantaneously to both the user and the dynamic data model, and can
seamlessly update the presentation accordingly. This really is a new level of Ajax development that transcends
the features of level-four Enhanced Ajax frameworks, and completely avoids the prevalent issues with client-
side development in JavaScript. ICEfaces not only provides a natural migration path for legacy Java Enterprise
applications to richer Ajax-based features, but it opens the door to a whole new class of web applications with
powerful dynamic features not available in other Ajax technologies.
A Natural Migration Path for JSP Applications
OK, so ICEfaces enables you to bring tremendous new rich interactive features to your application and allows
you to reuse your back-end infrastructure, but rewriting your entire application presentation layer in JSF might
still be a pretty formidable task. A large multi-page JSP application will surely be multi-faceted, and there will
likely be areas in the application that warrant priority attention, and will provide quick ROI for your enterprise.
So what are the options for incrementally upgrading the application to leverage ICEfaces?
To start with, it is possible to add JSF regions into a JSP page using the standard JSP <include> mechanism,
which means that dynamic ICEfaces regions can be added in the same manner. Because the JSP page and the
ICEfaces <include> can share the same backing beans, data bindings can be included in both the JSP regions
of the page and the ICEfaces regions of the page. The data model of the application can be easily shared in this
manner. If users are interacting with the JSP region of the page, they will get the normal user-initiated, full-
page refresh characteristics of legacy JSP applications, but if users are interacting with the ICEfaces region, they
will experience the rich presentation that ICEfaces delivers. And of course, you are not limited to a single
ICEfaces region in the page, so additional regions of the page can be incrementally converted over time. While
multiple ICEfaces regions can share a common data model by referencing the same backing beans, each region
acts within its own application lifecycle. This means that interaction in one ICEfaces region will not automatically
result in updated presentation in other regions, but the limitation can be easily overcome using ICEfaces Ajax
Push techniques. Basically, a common trigger point is established for all ICEfaces regions in the page, and when
one region recognizes a state change, all regions can be triggered to update asynchronously. The concept of
integrating multiple ICEfaces regions into an existing JSP application page is illustrated in Figure 10 below.
© 2006 ICEsoft Technologies Inc. 12
Download ICEfaces
http://www.icesoft.com/downloads/
Figure 10: ICEfaces Included in Legacy JSP Application
Transcend the Hype with ICEfaces
Let’s circle back to where we started to summarize our findings. Your original goal was to cut through the hype
around Ajax in the industry and find a way to bring the benefits of Ajax to your Enterprise in an effective, timely
manner. We have discussed the levels and perils of Ajax development, and have shown how ICEfaces
represents a new, more powerful level of Ajax that overcomes the obstacles of JavaScript development.
Specifically, ICEfaces delivers the following:
1. Ajax development in pure Java without JavaScript development, and without application fragmentation.
2. Thin Client Ajax with instantaneous reaction to user interaction and dynamic data model changes, with
both resulting in seamless incremental update of the presentation.
3. A Java Enterprise, standards-compliant approach that fosters the reuse of existing infrastructure,
development tools, and best practices that leverages the core competencies of your development team.
4. A natural migration path that enables you to incrementally add rich ICEfaces regions to existing legacy JSP
applications.
As we slide over the peak of inflated expectations on the Ajax hype cycle, do not fear the dreaded trough of
disillusionment in which most Ajax technologies will deposit you. Let ICEfaces launch you off the peak, over the
trough, and onto the slope of enlightenment. We will see you on the other side as you make the gentle climb to
the plateau of productivity.
© 2006 ICEsoft Technologies Inc. 13
Download ICEfaces
http://www.icesoft.com/downloads/
Figure 11: Transcend the Hype with ICEfaces
© 2006 ICEsoft Technologies Inc. 14
Download ICEfaces
http://www.icesoft.com/downloads/
References
1. Gartner Press Release (2006). Gartner’s 2006 Emerging Technologies Hype Cycle Highlights Key Technology Themes
(www.gartner.com). Article retrieved Sept 2006 from http://www.gartner.com/it/page.jsp?id=495475.
2. Valdes, Ray (2006). Snippets, widgets and other levels of Ajax development. Application Development Trends
(www.adtmag.com). Article retrieved August 2006 from http://www.adtmag.com/article.aspx?id=17953.
3. Crane, Dave and Pascarello, Eric with James, Darren. Ajax In Action. Manning Publications Co. 2005. Available online at
http://www.manning.com/crane.
No part of this publication may be copied in any form, by photocopy, microfilm, retrieval system, or by any other means now known or hereafter invented
without the prior written permission of ICEsoft Technologies, Inc.
The content in this guide is protected under copyright law even if it is not distributed with software that includes an end user license agreement.
The content in this document is furnished for informational use only, is subject to change without notice, and should not be construed as a commitment by
ICEsoft Technologies, Inc.
ICEsoft Technologies, Inc. assumes no responsibility or liability for any errors or inaccuracies that may appear in the informational content contained in this
document.
ICEfaces, ICEbrowser, and ICEpdf are trademarks of ICEsoft Technologies, Inc.
Sun, Sun Microsystems, the Sun logo, Solaris, Java and The Network is The Computer are trademarks or registered trademarks of Sun Microsystems, Inc. in
the United States and in other countries.
All other trademarks mentioned herein are the property of their respective owners.
Copyright 2007 ICEsoft Technologies, Inc. All rights reserved.
About ICEsoft
ICEsoft Technologies, Inc. , The Rich Web Company, is the leading provider of
standards-compliant, Ajax-based solutions for creating commercial quality pure Java rich
web applications.
Our Portfolio of enterprise level Java products includes:
• ICEfaces – the industry's first standards-compliant Ajax based solution for rapidly
creating all Java rich web applications that are easily maintained, extended, and
scaled, at very low cost.
• ICEbrowser – the most widely distributed Java browser in the world for rendering
web content into Java enterprise applications.
• ICEreader – a robust HTML/XML Web renderer with outstanding capabilities for
developers who need to implement HTML-centric search and navigation capabilities
in a Java application.
• ICEpdf – the leading Java PDF document rendering and viewing solution designed
to be easily integrated into Java enterprise applications.
As the leading worldwide provider of Java browser technology, our global product
deployments exceed 10 million units worldwide. Customers utilizing our Java browser and
PDF technologies in their deployments include IBM, BEA, Oracle, Borland, Cisco, Nokia,
NEC, Boeing, Lockheed Martin, and Barclays.
ICEsoft Technologies, Inc. Suite 300, 1717 10th St. NW
Calgary, Alberta, Canada
T2M 4S2
Toll Free: 1-877-263-3822 USA & Canada
Main: +001 (403) 663-3322
Fax: +001 (403) 663-3320
For additional information, please visit the ICEsoft website:
http://www.icesoft.com/
August 2006