<!--
  ~ Licensed to the Apache Software Foundation (ASF) under one or more
  ~     contributor license agreements.  See the NOTICE file distributed with
  ~     this work for additional information regarding copyright ownership.
  ~     The ASF licenses this file to You under the Apache License, Version 2.0
  ~     (the "License"); you may not use this file except in compliance with
  ~     the License.  You may obtain a copy of the License at
  ~
  ~         http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~     Unless required by applicable law or agreed to in writing, software
  ~     distributed under the License is distributed on an "AS IS" BASIS,
  ~     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~     See the License for the specific language governing permissions and
  ~     limitations under the License.
  -->
<html>
    <head>
        <META HTTP-EQUIV="Pragma" CONTENT="no-cache"> 
        <META HTTP-EQUIV="Expires" CONTENT="-1"> 
    </head>
    <body>
    <script>
        function processUrl()
        {

            var pos = url.indexOf("?");
            url = pos != -1 ? url.substr(pos + 1) : "";
            if (!parent._ie_firstload) {
                parent.BrowserHistory.setBrowserURL(url);
                try {
                    parent.BrowserHistory.browserURLChange(url);
                } catch(e) { }
            } else {
                parent._ie_firstload = false;
            }
        }

        var url = document.location.href;
        processUrl();
        document.write(encodeURIComponent(url));
    </script>
    Hidden frame for Browser History support.
    </body>
</html>
