diff --git a/TestON/TAI/src/EditorScripts/Delete.png b/TestON/TAI/src/EditorScripts/Delete.png
new file mode 100644
index 0000000..8920cab
--- /dev/null
+++ b/TestON/TAI/src/EditorScripts/Delete.png
Binary files differ
diff --git a/TestON/TAI/src/EditorScripts/Warning.png b/TestON/TAI/src/EditorScripts/Warning.png
new file mode 100644
index 0000000..0fa0b0b
--- /dev/null
+++ b/TestON/TAI/src/EditorScripts/Warning.png
Binary files differ
diff --git a/TestON/TAI/src/EditorScripts/blank.png b/TestON/TAI/src/EditorScripts/blank.png
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/TAI/src/EditorScripts/blank.png
diff --git a/TestON/TAI/src/EditorScripts/clike.js b/TestON/TAI/src/EditorScripts/clike.js
new file mode 100644
index 0000000..3c510a0
--- /dev/null
+++ b/TestON/TAI/src/EditorScripts/clike.js
@@ -0,0 +1,445 @@
+CodeMirror.defineMode("clike", function(config, parserConfig) {
+  var indentUnit = config.indentUnit,
+      keywords = parserConfig.keywords || {},
+      blockKeywords = parserConfig.blockKeywords || {},
+      atoms = parserConfig.atoms || {},
+      hooks = parserConfig.hooks || {},
+      multiLineStrings = parserConfig.multiLineStrings;
+  var isOperatorChar = /[+\-*&%=<>!?|\/]/;
+
+  var curPunc;
+
+  function tokenBase(stream, state) {
+    var ch = stream.next();
+    
+    if (hooks[ch]) {
+      var result = hooks[ch](stream, state);
+      if (result !== false) return result;
+    }
+    if (ch == '"' || ch == "'") {
+      state.tokenize = tokenString(ch);
+      return state.tokenize(stream, state);
+    }
+    if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
+      curPunc = ch;
+      return null;
+    }
+    //if (/\d/.test(ch)) {
+     // stream.eatWhile(/[\w\.]/);
+    //  return "number";
+   // }
+    if (ch == "/") {
+      if (stream.eat("*")) {
+        state.tokenize = tokenComment;
+        return tokenComment(stream, state);
+      }
+      if (stream.eat("/")) {
+        stream.skipToEnd();
+        return "comment";
+      }
+    }
+
+
+
+
+/*   if (ch == "!") {
+      if (stream.eat("!")) {
+        if (stream.eat("!")) {  
+          if (stream.eat(" ")) {
+   
+            stream.skipToEnd();
+            return "log";
+         }
+        }
+      }
+   }
+*/
+
+
+
+
+if (ch == "S") {
+    if (stream.eat("T")) {
+        if (stream.eat("A")) {
+            if (stream.eat("R")) {
+                stream.skipToEnd();
+                return "log_start_end_case";
+            }             
+        } else if (stream.eat("E")) {
+            if (stream.eat("P")) { 
+               stream.skipToEnd();
+               return "log_step";
+            }
+        }
+    }
+}
+
+
+
+
+
+
+
+
+if (ch == "S") {
+    if (stream.eat("T")) {
+        if (stream.eat("E")) {
+          if (stream.eat("P")) {
+
+            stream.skipToEnd();
+            return "log_step";
+         }
+      }
+      }
+    }
+
+
+
+if (ch == "P" && stream.eat("A") && stream.eat("S") && stream.eat("S") && stream.eat("E") && stream.eat("D") ) {
+            return "log_pass";
+    }
+
+
+
+
+
+
+   if (ch == "I") {
+    if (stream.eat("N")) {
+        if (stream.eat("F")) {
+          if (stream.eat("O")) {
+
+            stream.skipToEnd();
+            return "log_info";
+         }
+      }
+      }
+    }
+
+
+
+
+
+
+
+
+    if (ch == "D") {
+        if (stream.eat("E")) {
+            if (stream.eat("S")) {
+                if (stream.eat("C")) {
+                   stream.skipToEnd();
+                   return "log_description";
+                }
+            } else if(stream.eat("B")) {
+                if(stream.eat("U")) {
+                    if(stream.eat("G")) {
+                        stream.skipToEnd();
+                        return "log_debug";
+                    }
+                }
+           }                   
+       }
+   }
+
+
+
+
+
+
+   if (ch == "-") {
+   
+      if (stream.eat("-")) {
+        if (stream.eat("-")) {
+          if (stream.eat(" ")) {
+     
+            stream.skipToEnd();
+            return "log_error_warn";
+         }
+      }
+      }
+    }
+
+
+
+
+
+  if (ch == "+") {
+     if (stream.eat("+")) {
+        if (stream.eat("+")) {
+          if (stream.eat(" ")) {
+
+            stream.skipToEnd();
+            return "log_pass";
+         }
+      }
+      }
+    }
+
+
+
+
+
+
+
+
+if (ch == "E") {
+   
+      if (stream.eat("N")) {
+        if (stream.eat("D")) {
+          if (stream.eat("C")) {
+           if (stream.eat("A")) {
+             if (stream.eat("S"))  {
+
+               stream.skipToEnd();
+               return "log_start_end_case";
+             }
+           }
+         }
+      }
+      }
+    }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    if (isOperatorChar.test(ch)) {
+      stream.eatWhile(isOperatorChar);
+      return "operator";
+    }
+    stream.eatWhile(/[\w\$_]/);
+    var cur = stream.current();
+    if (keywords.propertyIsEnumerable(cur)) {
+      if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
+      return "keyword";
+    }
+    if (atoms.propertyIsEnumerable(cur)) return "atom";
+    return "word";
+  }
+
+  function tokenString(quote) {
+    return function(stream, state) {
+      var escaped = false, next, end = false;
+      while ((next = stream.next()) != null) {
+        if (next == quote && !escaped) {end = true; break;}
+        escaped = !escaped && next == "\\";
+      }
+      if (end || !(escaped || multiLineStrings))
+        state.tokenize = null;
+      return "string";
+    };
+  }
+
+  function tokenComment(stream, state) {
+    var maybeEnd = false, ch;
+    while (ch = stream.next()) {
+      if (ch == "/" && maybeEnd) {
+        state.tokenize = null;
+        break;
+      }
+      maybeEnd = (ch == "*");
+    }
+    return "comment";
+  }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  function Context(indented, column, type, align, prev) {
+    this.indented = indented;
+    this.column = column;
+    this.type = type;
+    this.align = align;
+    this.prev = prev;
+  }
+  function pushContext(state, col, type) {
+    return state.context = new Context(state.indented, col, type, null, state.context);
+  }
+  function popContext(state) {
+    var t = state.context.type;
+    if (t == ")" || t == "]" || t == "}")
+      state.indented = state.context.indented;
+    return state.context = state.context.prev;
+  }
+
+  // Interface
+
+  return {
+    startState: function(basecolumn) {
+      return {
+        tokenize: null,
+        context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
+        indented: 0,
+        startOfLine: true
+      };
+    },
+
+    token: function(stream, state) {
+      var ctx = state.context;
+      if (stream.sol()) {
+        if (ctx.align == null) ctx.align = false;
+        state.indented = stream.indentation();
+        state.startOfLine = true;
+      }
+      if (stream.eatSpace()) return null;
+      curPunc = null;
+      var style = (state.tokenize || tokenBase)(stream, state);
+      if (style == "comment" || style == "meta") return style;
+      if (ctx.align == null) ctx.align = true;
+
+      if ((curPunc == ";" || curPunc == ":") && ctx.type == "statement") popContext(state);
+      else if (curPunc == "{") pushContext(state, stream.column(), "}");
+      else if (curPunc == "[") pushContext(state, stream.column(), "]");
+      else if (curPunc == "(") pushContext(state, stream.column(), ")");
+      else if (curPunc == "}") {
+        while (ctx.type == "statement") ctx = popContext(state);
+        if (ctx.type == "}") ctx = popContext(state);
+        while (ctx.type == "statement") ctx = popContext(state);
+      }
+      else if (curPunc == ctx.type) popContext(state);
+      else if (ctx.type == "}" || ctx.type == "top" || (ctx.type == "statement" && curPunc == "newstatement"))
+        pushContext(state, stream.column(), "statement");
+      state.startOfLine = false;
+      return style;
+    },
+
+    indent: function(state, textAfter) {
+      if (state.tokenize != tokenBase && state.tokenize != null) return 0;
+      var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
+      if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
+      var closing = firstChar == ctx.type;
+      if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : indentUnit);
+      else if (ctx.align) return ctx.column + (closing ? 0 : 1);
+      else return ctx.indented + (closing ? 0 : indentUnit);
+    },
+
+    electricChars: "{}"
+  };
+});
+
+(function() {
+  function words(str) {
+    var obj = {}, words = str.split(" ");
+    for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+    return obj;
+  }
+  var cKeywords = "auto if break int case long char register continue return default short do sizeof " +
+    "double static else struct entry switch extern typedef float union for unsigned " +
+    "goto while enum void const signed volatile";
+
+  function cppHook(stream, state) {
+    if (!state.startOfLine) return false;
+    stream.skipToEnd();
+    return "meta";
+  }
+
+  // C#-style strings where "" escapes a quote.
+  function tokenAtString(stream, state) {
+    var next;
+    while ((next = stream.next()) != null) {
+      if (next == '"' && !stream.eat('"')) {
+        state.tokenize = null;
+        break;
+      }
+    }
+    return "string";
+  }
+
+  CodeMirror.defineMIME("text/x-csrc", {
+    name: "clike",
+    keywords: words(cKeywords),
+    blockKeywords: words("case do else for if switch while struct"),
+    atoms: words("null"),
+    hooks: {"#": cppHook}
+  });
+  CodeMirror.defineMIME("text/x-c++src", {
+    name: "clike",
+    keywords: words(cKeywords + " asm dynamic_cast namespace reinterpret_cast try bool explicit new " +
+                    "static_cast typeid catch operator template typename class friend private " +
+                    "this using const_cast inline public throw virtual delete mutable protected " +
+                    "wchar_t"),
+    blockKeywords: words("catch class do else finally for if struct switch try while"),
+    atoms: words("true false null"),
+    hooks: {"#": cppHook}
+  });
+  CodeMirror.defineMIME("text/x-java", {
+    name: "clike",
+    keywords: words("abstract assert boolean break byte case catch char class const continue default " + 
+                    "do double else enum extends final finally float for goto if implements import " +
+                    "instanceof int interface long native new package private protected public " +
+                    "return short static strictfp super switch synchronized this throw throws transient " +
+                    "try void volatile while"),
+    blockKeywords: words("catch class do else finally for if switch try while"),
+    atoms: words("true false null"),
+    hooks: {
+      "@": function(stream, state) {
+        stream.eatWhile(/[\w\$_]/);
+        return "meta";
+      }
+    }
+  });
+  CodeMirror.defineMIME("text/x-csharp", {
+    name: "clike",
+    keywords: words(" abstract as base bool break byte case catch char checked class const continue decimal" + 
+                    " default delegate do double else enum event explicit extern finally fixed float for" + 
+                    " foreach goto if implicit in int interface internal is lock long namespace new object" + 
+                    " operator out override params private protected public readonly ref return sbyte sealed short" + 
+                    " sizeof stackalloc static string struct switch this throw try typeof uint ulong unchecked" + 
+                    " unsafe ushort using virtual void volatile while add alias ascending descending dynamic from get" + 
+                    " global group into join let orderby partial remove select set value var yield"),
+    blockKeywords: words("catch class do else finally for foreach if struct switch try while"),
+    atoms: words("true false null"),
+    hooks: {
+      "@": function(stream, state) {
+        if (stream.eat('"')) {
+          state.tokenize = tokenAtString;
+          return tokenAtString(stream, state);
+        }
+        stream.eatWhile(/[\w\$_]/);
+        return "meta";
+      }
+    }
+  });
+}());
+
diff --git a/TestON/TAI/src/EditorScripts/codemirror.css b/TestON/TAI/src/EditorScripts/codemirror.css
new file mode 100644
index 0000000..2ee8c95
--- /dev/null
+++ b/TestON/TAI/src/EditorScripts/codemirror.css
@@ -0,0 +1,145 @@
+.CodeMirror {
+  line-height: 1em;
+  font-family: calibri;
+  font-color: black;
+}
+
+.CodeMirror-scroll {
+  overflow: auto;
+  height: 50%;
+  /* This is needed to prevent an IE[67] bug where the scrolled content
+     is visible outside of the scrolling box. */
+  position: relative;
+  outline: none;
+}
+
+.CodeMirror-gutter {
+  position: absolute; left: 0; top: 0;
+  z-index: 10;
+  background-color: #cccccc;
+  border-right: 1px solid #eee;
+  min-width: 2em;
+  height: 100%;
+}
+.CodeMirror-gutter-text {
+  color: black;
+  text-align: right;
+  padding: .2em .2em .4em .4em;
+  white-space: pre !important;
+}
+.CodeMirror-lines {
+  padding: .4em;
+  white-space: pre;
+}
+
+.CodeMirror pre {
+  -moz-border-radius: 0;
+  -webkit-border-radius: 0;
+  -o-border-radius: 0;
+  border-radius: 0;
+  border-width: 0; margin: 0; padding: 0; background: transparent;
+  font-family: inherit;
+  font-size: 0.8em;
+  padding: 0; margin: 0;
+  white-space: pre;
+  word-wrap: normal;
+  line-height: inherit;
+  color: inherit;
+}
+
+.CodeMirror-wrap pre {
+  word-wrap: break-word;
+  white-space: pre-wrap;
+  word-break: normal;
+}
+.CodeMirror-wrap .CodeMirror-scroll {
+  overflow-x: hidden;
+}
+
+.CodeMirror textarea {
+  outline: black !important;
+  font-color:black;
+}
+
+.CodeMirror pre.CodeMirror-cursor {
+  z-index: 10;
+  position: absolute;
+  visibility: hidden;
+  border-left: 1px solid black;
+  border-right: none;
+  width: 0;
+}
+.cm-keymap-fat-cursor pre.CodeMirror-cursor {
+  width: auto;
+  border: 0;
+  background: #000000;
+  background: rgba(0, 200, 0, .4);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#6600c800, endColorstr=#4c00c800);
+}
+/* Kludge to turn off filter in ie9+, which also accepts rgba */
+.cm-keymap-fat-cursor pre.CodeMirror-cursor:not(#nonsense_id) {
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+}
+.CodeMirror pre.CodeMirror-cursor.CodeMirror-overwrite {}
+.CodeMirror-focused pre.CodeMirror-cursor {
+  visibility: visible;
+}
+
+div.CodeMirror-selected { background: #d9d9d9; }
+.CodeMirror-focused div.CodeMirror-selected { background: #d7d4f0; }
+
+.CodeMirror-searching {
+  background: #ffa;
+  background: rgba(255, 255, 0, .4);
+}
+
+/* Default theme */
+
+.cm-s-default span.cm-keyword {color: #708;}
+.cm-s-default span.cm-atom {color: #219;}
+.cm-s-default span.cm-number {color: #164;}
+.cm-s-default span.cm-def {color: #00f;}
+.cm-s-default span.cm-variable {color: black;}
+.cm-s-default span.cm-variable-2 {color: #05a;}
+.cm-s-default span.cm-variable-3 {color: #085;}
+.cm-s-default span.cm-property {color: black;}
+.cm-s-default span.cm-operator {color: black;}
+.cm-s-default span.cm-comment {color: #a50;}
+.cm-s-default span.cm-string {color: #a11;}
+.cm-s-default span.cm-string-2 {color: #f50;}
+.cm-s-default span.cm-meta {color: #555;}
+.cm-s-default span.cm-error {color: #f00;}
+.cm-s-default span.cm-qualifier {color: #555;}
+.cm-s-default span.cm-builtin {color: #30a;}
+.cm-s-default span.cm-bracket {color: #cc7;}
+.cm-s-default span.cm-tag {color: #170;}
+.cm-s-default span.cm-attribute {color: #00c;}
+.cm-s-default span.cm-header {color: transparent;}
+.cm-s-default span.cm-quote {color: #090;}
+.cm-s-default span.cm-hr {color: #999;}
+.cm-s-default span.cm-link {color: #00c;}
+
+
+
+
+.cm-s-default span.cm-log {color: #000000;}
+.cm-s-default span.cm-log_error_warn {color: #FF0000;}
+.cm-s-default span.cm-log_pass {color: #00CC00;}
+.cm-s-default span.cm-log_step {color: #0000FF;}
+.cm-s-default span.cm-log_start_end_case {color: #FF0000;}
+
+.cm-s-default span.cm-log_debug {color: #FFB90F;}
+.cm-s-default span.cm-log_description {color: #0000FF;}
+.cm-s-default span.cm-log_info {color: #00529B;background-color: #BDE5F8;}
+
+
+
+
+/*span.cm-header, span.cm-strong {font-weight: bold;}*/
+/*span.cm-em {font-style: italic;}*/
+/*span.cm-emstrong {font-style: italic; font-weight: bold;}*/
+span.cm-link {text-decoration: underline;}
+
+div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
+div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
+
diff --git a/TestON/TAI/src/EditorScripts/codemirror.js b/TestON/TAI/src/EditorScripts/codemirror.js
new file mode 100644
index 0000000..19ae5f0
--- /dev/null
+++ b/TestON/TAI/src/EditorScripts/codemirror.js
@@ -0,0 +1,3085 @@
+// All functions that need access to the editor's state live inside
+// the CodeMirror function. Below that, at the bottom of the file,
+// some utilities are defined.
+//
+// CodeMirror is the only global var we claim
+var CodeMirror = (function() {
+  // This is the function that produces an editor instance. Its
+  // closure is used to store the editor state.
+  function CodeMirror(place, givenOptions) {
+    // Determine effective options based on given values and defaults.
+    var options = {}, defaults = CodeMirror.defaults;
+    for (var opt in defaults)
+      if (defaults.hasOwnProperty(opt))
+        options[opt] = (givenOptions && givenOptions.hasOwnProperty(opt) ? givenOptions : defaults)[opt];
+
+    // The element in which the editor lives.
+    var wrapper = document.createElement("div");
+    wrapper.className = "CodeMirror" + (options.lineWrapping ? " CodeMirror-wrap" : "");
+    // This mess creates the base DOM structure for the editor.
+    wrapper.innerHTML =
+      '<div style="overflow: hidden; position: relative; width: 3px; height: 3px;">' + // Wraps and hides input textarea
+        '<textarea style="position: absolute; padding: 0; width: 1px; height: 1em" wrap="off" ' +
+          'autocorrect="off" autocapitalize="off"></textarea></div>' +
+      '<div class="CodeMirror-scroll" tabindex="-1">' +
+        '<div style="position: relative">' + // Set to the height of the text, causes scrolling
+          '<div style="position: relative">' + // Moved around its parent to cover visible view
+            '<div class="CodeMirror-gutter"><div class="CodeMirror-gutter-text"></div></div>' +
+            // Provides positioning relative to (visible) text origin
+            '<div class="CodeMirror-lines"><div style="position: relative; z-index: 0">' +
+              '<div style="position: absolute; width: 100%; height:0; overflow: hidden; visibility: hidden;"></div>' +
+              '<pre class="CodeMirror-cursor">&#160;</pre>' + // Absolutely positioned blinky cursor
+              '<div style="position: relative; z-index: -1"></div><div></div>' + // DIVs containing the selection and the actual code
+            '</div></div></div></div></div>';
+    if (place.appendChild) place.appendChild(wrapper); else place(wrapper);
+    // I've never seen more elegant code in my life.
+    var inputDiv = wrapper.firstChild, input = inputDiv.firstChild,
+        scroller = wrapper.lastChild, code = scroller.firstChild,
+        mover = code.firstChild, gutter = mover.firstChild, gutterText = gutter.firstChild,
+        lineSpace = gutter.nextSibling.firstChild, measure = lineSpace.firstChild,
+        cursor = measure.nextSibling, selectionDiv = cursor.nextSibling,
+        lineDiv = selectionDiv.nextSibling;
+    themeChanged(); keyMapChanged();
+    // Needed to hide big blue blinking cursor on Mobile Safari
+    if (ios) input.style.width = "0px";
+    if (!webkit) lineSpace.draggable = true;
+    lineSpace.style.outline = "none";
+    if (options.tabindex != null) input.tabIndex = options.tabindex;
+    if (options.autofocus) focusInput();
+    if (!options.gutter && !options.lineNumbers) gutter.style.display = "none";
+    // Needed to handle Tab key in KHTML
+    if (khtml) inputDiv.style.height = "1px", inputDiv.style.position = "absolute";
+
+    // Check for problem with IE innerHTML not working when we have a
+    // P (or similar) parent node.
+    try { stringWidth("x"); }
+    catch (e) {
+      if (e.message.match(/runtime/i))
+        e = new Error("A CodeMirror inside a P-style element does not work in Internet Explorer. (innerHTML bug)");
+      throw e;
+    }
+
+    // Delayed object wrap timeouts, making sure only one is active. blinker holds an interval.
+    var poll = new Delayed(), highlight = new Delayed(), blinker;
+
+    // mode holds a mode API object. doc is the tree of Line objects,
+    // work an array of lines that should be parsed, and history the
+    // undo history (instance of History constructor).
+    var mode, doc = new BranchChunk([new LeafChunk([new Line("")])]), work, focused;
+    loadMode();
+    // The selection. These are always maintained to point at valid
+    // positions. Inverted is used to remember that the user is
+    // selecting bottom-to-top.
+    var sel = {from: {line: 0, ch: 0}, to: {line: 0, ch: 0}, inverted: false};
+    // Selection-related flags. shiftSelecting obviously tracks
+    // whether the user is holding shift.
+    var shiftSelecting, lastClick, lastDoubleClick, lastScrollPos = 0, draggingText,
+        overwrite = false, suppressEdits = false;
+    // Variables used by startOperation/endOperation to track what
+    // happened during the operation.
+    var updateInput, userSelChange, changes, textChanged, selectionChanged, leaveInputAlone,
+        gutterDirty, callbacks;
+    // Current visible range (may be bigger than the view window).
+    var displayOffset = 0, showingFrom = 0, showingTo = 0, lastSizeC = 0;
+    // bracketHighlighted is used to remember that a bracket has been
+    // marked.
+    var bracketHighlighted;
+    // Tracks the maximum line length so that the horizontal scrollbar
+    // can be kept static when scrolling.
+    var maxLine = "", maxWidth;
+    var tabCache = {};
+
+    // Initialize the content.
+    operation(function(){setValue(options.value || ""); updateInput = false;})();
+    var history = new History();
+
+    // Register our event handlers.
+    connect(scroller, "mousedown", operation(onMouseDown));
+    connect(scroller, "dblclick", operation(onDoubleClick));
+    connect(lineSpace, "selectstart", e_preventDefault);
+    // Gecko browsers fire contextmenu *after* opening the menu, at
+    // which point we can't mess with it anymore. Context menu is
+    // handled in onMouseDown for Gecko.
+    if (!gecko) connect(scroller, "contextmenu", onContextMenu);
+    connect(scroller, "scroll", function() {
+      lastScrollPos = scroller.scrollTop;
+      updateDisplay([]);
+      if (options.fixedGutter) gutter.style.left = scroller.scrollLeft + "px";
+      if (options.onScroll) options.onScroll(instance);
+    });
+    connect(window, "resize", function() {updateDisplay(true);});
+    connect(input, "keyup", operation(onKeyUp));
+    connect(input, "input", fastPoll);
+    connect(input, "keydown", operation(onKeyDown));
+    connect(input, "keypress", operation(onKeyPress));
+    connect(input, "focus", onFocus);
+    connect(input, "blur", onBlur);
+
+    if (options.dragDrop) {
+      connect(lineSpace, "dragstart", onDragStart);
+      function drag_(e) {
+        if (options.onDragEvent && options.onDragEvent(instance, addStop(e))) return;
+        e_stop(e);
+      }
+      connect(scroller, "dragenter", drag_);
+      connect(scroller, "dragover", drag_);
+      connect(scroller, "drop", operation(onDrop));
+    }
+    connect(scroller, "paste", function(){focusInput(); fastPoll();});
+    connect(input, "paste", fastPoll);
+    connect(input, "cut", operation(function(){
+      if (!options.readOnly) replaceSelection("");
+    }));
+
+    // Needed to handle Tab key in KHTML
+    if (khtml) connect(code, "mouseup", function() {
+        if (document.activeElement == input) input.blur();
+        focusInput();
+    });
+
+    // IE throws unspecified error in certain cases, when
+    // trying to access activeElement before onload
+    var hasFocus; try { hasFocus = (document.activeElement == input); } catch(e) { }
+    if (hasFocus || options.autofocus) setTimeout(onFocus, 20);
+    else onBlur();
+
+    function isLine(l) {return l >= 0 && l < doc.size;}
+    // The instance object that we'll return. Mostly calls out to
+    // local functions in the CodeMirror function. Some do some extra
+    // range checking and/or clipping. operation is used to wrap the
+    // call so that changes it makes are tracked, and the display is
+    // updated afterwards.
+    var instance = wrapper.CodeMirror = {
+       myFunction:  myFunction,    
+      getValue: getValue,
+      getLineNumber: getLineNumber,
+      cursorLeftPos: cursorLeftPos,
+      cursorTopPos:cursorTopPos,
+      setValue: operation(setValue),
+      getSelection: getSelection,
+      replaceSelection: operation(replaceSelection),
+      focus: function(){window.focus(); focusInput(); onFocus(); fastPoll();},
+      setOption: function(option, value) {
+        var oldVal = options[option];
+        options[option] = value;
+        if (option == "mode" || option == "indentUnit") loadMode();
+        else if (option == "readOnly" && value == "nocursor") {onBlur(); input.blur();}
+        else if (option == "readOnly" && !value) {resetInput(true);}
+        else if (option == "theme") themeChanged();
+        else if (option == "lineWrapping" && oldVal != value) operation(wrappingChanged)();
+        else if (option == "tabSize") updateDisplay(true);
+        else if (option == "keyMap") keyMapChanged();
+        if (option == "lineNumbers" || option == "gutter" || option == "firstLineNumber" || option == "theme") {
+          gutterChanged();
+          updateDisplay(true);
+        }
+      },
+      getOption: function(option) {return options[option];},
+      undo: operation(undo),
+      redo: operation(redo),
+      indentLine: operation(function(n, dir) {
+        if (typeof dir != "string") {
+          if (dir == null) dir = options.smartIndent ? "smart" : "prev";
+          else dir = dir ? "add" : "subtract";
+        }
+        if (isLine(n)) indentLine(n, dir);
+      }),
+      indentSelection: operation(indentSelected),
+      historySize: function() {return {undo: history.done.length, redo: history.undone.length};},
+      clearHistory: function() {history = new History();},
+      matchBrackets: operation(function(){matchBrackets(true);}),
+      getTokenAt: operation(function(pos) {
+        pos = clipPos(pos);
+        return getLine(pos.line).getTokenAt(mode, getStateBefore(pos.line), pos.ch);
+      }),
+      getStateAfter: function(line) {
+        line = clipLine(line == null ? doc.size - 1: line);
+        return getStateBefore(line + 1);
+      },
+      cursorCoords: function(start, mode) {
+        if (start == null) start = sel.inverted;
+        return this.charCoords(start ? sel.from : sel.to, mode);
+      },
+      charCoords: function(pos, mode) {
+        pos = clipPos(pos);
+        if (mode == "local") return localCoords(pos, false);
+        if (mode == "div") return localCoords(pos, true);
+        return pageCoords(pos);
+      },
+      coordsChar: function(coords) {
+        var off = eltOffset(lineSpace);
+        return coordsChar(coords.x - off.left, coords.y - off.top);
+      },
+      markText: operation(markText),
+      setBookmark: setBookmark,
+      findMarksAt: findMarksAt,
+      setMarker: operation(addGutterMarker),
+      clearMarker: operation(removeGutterMarker),
+      setLineClass: operation(setLineClass),
+      updateGutter: updateGutter,
+
+      hideLine: operation(function(h) {return setLineHidden(h, true);}),
+      showLine: operation(function(h) {return setLineHidden(h, false);}),
+      onDeleteLine: function(line, f) {
+        if (typeof line == "number") {
+          if (!isLine(line)) return null;
+          line = getLine(line);
+        }
+        (line.handlers || (line.handlers = [])).push(f);
+        return line;
+      },
+      lineInfo: lineInfo,
+      addWidget: function(pos, node, scroll, vert, horiz) {
+        pos = localCoords(clipPos(pos));
+        var top = pos.yBot, left = pos.x;
+        node.style.position = "absolute";
+        code.appendChild(node);
+        if (vert == "over") top = pos.y;
+        else if (vert == "near") {
+          var vspace = Math.max(scroller.offsetHeight, doc.height * textHeight()),
+              hspace = Math.max(code.clientWidth, lineSpace.clientWidth) - paddingLeft();
+          if (pos.yBot + node.offsetHeight > vspace && pos.y > node.offsetHeight)
+            top = pos.y - node.offsetHeight;
+          if (left + node.offsetWidth > hspace)
+            left = hspace - node.offsetWidth;
+        }
+        node.style.top = (top + paddingTop()) + "px";
+        node.style.left = node.style.right = "";
+        if (horiz == "right") {
+          left = code.clientWidth - node.offsetWidth;
+          node.style.right = "0px";
+        } else {
+          if (horiz == "left") left = 0;
+          else if (horiz == "middle") left = (code.clientWidth - node.offsetWidth) / 2;
+          node.style.left = (left + paddingLeft()) + "px";
+        }
+        if (scroll)
+          scrollIntoView(left, top, left + node.offsetWidth, top + node.offsetHeight);
+      },
+
+      lineCount: function() {return doc.size;},
+      clipPos: clipPos,
+      getCursor: function(start) {
+        if (start == null) start = sel.inverted;
+        return copyPos(start ? sel.from : sel.to);
+      },
+      somethingSelected: function() {return !posEq(sel.from, sel.to);},
+      setCursor: operation(function(line, ch, user) {
+        if (ch == null && typeof line.line == "number") setCursor(line.line, line.ch, user);
+        else setCursor(line, ch, user);
+      }),
+      setSelection: operation(function(from, to, user) {
+        (user ? setSelectionUser : setSelection)(clipPos(from), clipPos(to || from));
+      }),
+      getLine: function(line) {if (isLine(line)) return getLine(line).text;},
+      getLineHandle: function(line) {if (isLine(line)) return getLine(line);},
+      setLine: operation(function(line, text) {
+        if (isLine(line)) replaceRange(text, {line: line, ch: 0}, {line: line, ch: getLine(line).text.length});
+      }),
+      removeLine: operation(function(line) {
+        if (isLine(line)) replaceRange("", {line: line, ch: 0}, clipPos({line: line+1, ch: 0}));
+      }),
+      replaceRange: operation(replaceRange),
+      getRange: function(from, to) {return getRange(clipPos(from), clipPos(to));},
+
+      triggerOnKeyDown: operation(onKeyDown),
+      execCommand: function(cmd) {return commands[cmd](instance);},
+      // Stuff used by commands, probably not much use to outside code.
+      moveH: operation(moveH),
+      deleteH: operation(deleteH),
+      moveV: operation(moveV),
+      toggleOverwrite: function() {
+        if(overwrite){
+          overwrite = false;
+          cursor.className = cursor.className.replace(" CodeMirror-overwrite", "");
+        } else {
+          overwrite = true;
+          cursor.className += " CodeMirror-overwrite";
+        }
+      },
+
+      posFromIndex: function(off) {
+        var lineNo = 0, ch;
+        doc.iter(0, doc.size, function(line) {
+          var sz = line.text.length + 1;
+          if (sz > off) { ch = off; return true; }
+          off -= sz;
+          ++lineNo;
+        });
+        return clipPos({line: lineNo, ch: ch});
+      },
+      indexFromPos: function (coords) {
+        if (coords.line < 0 || coords.ch < 0) return 0;
+        var index = coords.ch;
+        doc.iter(0, coords.line, function (line) {
+          index += line.text.length + 1;
+        });
+        return index;
+      },
+      scrollTo: function(x, y) {
+        if (x != null) scroller.scrollLeft = x;
+        if (y != null) scroller.scrollTop = y;
+        updateDisplay([]);
+      },
+
+      operation: function(f){return operation(f)();},
+      compoundChange: function(f){return compoundChange(f);},
+      refresh: function(){
+        updateDisplay(true);
+        if (scroller.scrollHeight > lastScrollPos)
+          scroller.scrollTop = lastScrollPos;
+      },
+      getInputField: function(){return input;},
+      getWrapperElement: function(){return wrapper;},
+      getScrollerElement: function(){return scroller;},
+      getGutterElement: function(){return gutter;}
+    };
+
+    function getLine(n) { return getLineAt(doc, n); }
+    function updateLineHeight(line, height) {
+      gutterDirty = true;
+      var diff = height - line.height;
+      for (var n = line; n; n = n.parent) n.height += diff;
+    }
+
+    function setValue(code) {
+      var top = {line: 0, ch: 0};
+      updateLines(top, {line: doc.size - 1, ch: getLine(doc.size-1).text.length},
+                  splitLines(code), top, top);
+      updateInput = true;
+    }
+    function getValue() {
+      var text = [];
+      doc.iter(0, doc.size, function(line) { text.push(line.text); });
+      return text.join("\n");
+    }
+function cursorLeftPos() {
+    var pos = editor.cursorCoords();
+   return pos.x; 
+}
+
+function myFunction()
+{
+alert("I am an alert box!");
+}
+function cursorTopPos() {
+	 var pos = editor.cursorCoords();
+ 	return pos.yBot;
+}
+    function onMouseDown(e) {
+      setShift(e_prop(e, "shiftKey"));
+      // Check whether this is a click in a widget
+      for (var n = e_target(e); n != wrapper; n = n.parentNode)
+        if (n.parentNode == code && n != mover) return;
+
+      // See if this is a click in the gutter
+      for (var n = e_target(e); n != wrapper; n = n.parentNode)
+        if (n.parentNode == gutterText) {
+          if (options.onGutterClick)
+            options.onGutterClick(instance, indexOf(gutterText.childNodes, n) + showingFrom, e);
+            return e_preventDefault(e);
+        }
+
+      var start = posFromMouse(e);
+
+      switch (e_button(e)) {
+      case 3:
+        if (gecko && !mac) onContextMenu(e);
+        return;
+      case 2:
+        if (start) setCursor(start.line, start.ch, true);
+        setTimeout(focusInput, 20);
+        return;
+      }
+      // For button 1, if it was clicked inside the editor
+      // (posFromMouse returning non-null), we have to adjust the
+      // selection.
+      if (!start) {if (e_target(e) == scroller) e_preventDefault(e); return;}
+
+      if (!focused) onFocus();
+
+      var now = +new Date;
+      if (lastDoubleClick && lastDoubleClick.time > now - 400 && posEq(lastDoubleClick.pos, start)) {
+        e_preventDefault(e);
+        setTimeout(focusInput, 20);
+        return selectLine(start.line);
+      } else if (lastClick && lastClick.time > now - 400 && posEq(lastClick.pos, start)) {
+        lastDoubleClick = {time: now, pos: start};
+        e_preventDefault(e);
+        return selectWordAt(start);
+      } else { lastClick = {time: now, pos: start}; }
+
+      var last = start, going;
+      if (options.dragDrop && dragAndDrop && !options.readOnly && !posEq(sel.from, sel.to) &&
+          !posLess(start, sel.from) && !posLess(sel.to, start)) {
+        // Let the drag handler handle this.
+        if (webkit) lineSpace.draggable = true;
+        function dragEnd(e2) {
+          if (webkit) lineSpace.draggable = false;
+          draggingText = false;
+          up(); drop();
+          if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
+            e_preventDefault(e2);
+            setCursor(start.line, start.ch, true);
+            focusInput();
+          }
+        }
+        var up = connect(document, "mouseup", operation(dragEnd), true);
+        var drop = connect(scroller, "drop", operation(dragEnd), true);
+        draggingText = true;
+        // IE's approach to draggable
+        if (lineSpace.dragDrop) lineSpace.dragDrop();
+        return;
+      }
+      e_preventDefault(e);
+      setCursor(start.line, start.ch, true);
+
+      function extend(e) {
+        var cur = posFromMouse(e, true);
+        if (cur && !posEq(cur, last)) {
+          if (!focused) onFocus();
+          last = cur;
+          setSelectionUser(start, cur);
+          updateInput = false;
+          var visible = visibleLines();
+          if (cur.line >= visible.to || cur.line < visible.from)
+            going = setTimeout(operation(function(){extend(e);}), 150);
+        }
+      }
+
+      function done(e) {
+        clearTimeout(going);
+        var cur = posFromMouse(e);
+        if (cur) setSelectionUser(start, cur);
+        e_preventDefault(e);
+        focusInput();
+        updateInput = true;
+        move(); up();
+      }
+      var move = connect(document, "mousemove", operation(function(e) {
+        clearTimeout(going);
+        e_preventDefault(e);
+        if (!ie && !e_button(e)) done(e);
+        else extend(e);
+      }), true);
+      var up = connect(document, "mouseup", operation(done), true);
+    }
+    function onDoubleClick(e) {
+      for (var n = e_target(e); n != wrapper; n = n.parentNode)
+        if (n.parentNode == gutterText) return e_preventDefault(e);
+      var start = posFromMouse(e);
+      if (!start) return;
+      lastDoubleClick = {time: +new Date, pos: start};
+      e_preventDefault(e);
+      selectWordAt(start);
+    }
+    function onDrop(e) {
+      if (options.onDragEvent && options.onDragEvent(instance, addStop(e))) return;
+      e.preventDefault();
+      var pos = posFromMouse(e, true), files = e.dataTransfer.files;
+      if (!pos || options.readOnly) return;
+      if (files && files.length && window.FileReader && window.File) {
+        function loadFile(file, i) {
+          var reader = new FileReader;
+          reader.onload = function() {
+            text[i] = reader.result;
+            if (++read == n) {
+              pos = clipPos(pos);
+              operation(function() {
+                var end = replaceRange(text.join(""), pos, pos);
+                setSelectionUser(pos, end);
+              })();
+            }
+          };
+          reader.readAsText(file);
+        }
+        var n = files.length, text = Array(n), read = 0;
+        for (var i = 0; i < n; ++i) loadFile(files[i], i);
+      }
+      else {
+        try {
+          var text = e.dataTransfer.getData("Text");
+          if (text) {
+            compoundChange(function() {
+              var curFrom = sel.from, curTo = sel.to;
+              setSelectionUser(pos, pos);
+              if (draggingText) replaceRange("", curFrom, curTo);
+              replaceSelection(text);
+              focusInput();
+            });
+          }
+        }
+        catch(e){}
+      }
+    }
+    function onDragStart(e) {
+      var txt = getSelection();
+      e.dataTransfer.setData("Text", txt);
+      
+      // Use dummy image instead of default browsers image.
+      if (gecko || chrome) {
+        var img = document.createElement('img');
+        img.scr = 'data:image/gif;base64,R0lGODdhAgACAIAAAAAAAP///ywAAAAAAgACAAACAoRRADs='; //1x1 image
+        e.dataTransfer.setDragImage(img, 0, 0);
+      }
+    }
+
+    function doHandleBinding(bound, dropShift) {
+      if (typeof bound == "string") {
+        bound = commands[bound];
+        if (!bound) return false;
+      }
+      var prevShift = shiftSelecting;
+      try {
+        if (options.readOnly) suppressEdits = true;
+        if (dropShift) shiftSelecting = null;
+        bound(instance);
+      } catch(e) {
+        if (e != Pass) throw e;
+        return false;
+      } finally {
+        shiftSelecting = prevShift;
+        suppressEdits = false;
+      }
+      return true;
+    }
+    function handleKeyBinding(e) {
+      // Handle auto keymap transitions
+      var startMap = getKeyMap(options.keyMap), next = startMap.auto;
+      clearTimeout(maybeTransition);
+      if (next && !isModifierKey(e)) maybeTransition = setTimeout(function() {
+        if (getKeyMap(options.keyMap) == startMap) {
+          options.keyMap = (next.call ? next.call(null, instance) : next);
+        }
+      }, 50);
+
+      var name = keyNames[e_prop(e, "keyCode")], handled = false;
+      if (name == null || e.altGraphKey) return false;
+      if (e_prop(e, "altKey")) name = "Alt-" + name;
+      if (e_prop(e, "ctrlKey")) name = "Ctrl-" + name;
+      if (e_prop(e, "metaKey")) name = "Cmd-" + name;
+
+      var stopped = false;
+      function stop() { stopped = true; }
+
+      if (e_prop(e, "shiftKey")) {
+        handled = lookupKey("Shift-" + name, options.extraKeys, options.keyMap,
+                            function(b) {return doHandleBinding(b, true);}, stop)
+               || lookupKey(name, options.extraKeys, options.keyMap, function(b) {
+                 if (typeof b == "string" && /^go[A-Z]/.test(b)) return doHandleBinding(b);
+               }, stop);
+      } else {
+        handled = lookupKey(name, options.extraKeys, options.keyMap, doHandleBinding, stop);
+      }
+      if (stopped) handled = false;
+      if (handled) {
+        e_preventDefault(e);
+        restartBlink();
+        if (ie) { e.oldKeyCode = e.keyCode; e.keyCode = 0; }
+      }
+      return handled;
+    }
+    function handleCharBinding(e, ch) {
+      var handled = lookupKey("'" + ch + "'", options.extraKeys,
+                              options.keyMap, function(b) { return doHandleBinding(b, true); });
+      if (handled) {
+        e_preventDefault(e);
+        restartBlink();
+      }
+      return handled;
+    }
+
+    var lastStoppedKey = null, maybeTransition;
+    function onKeyDown(e) {
+      if (!focused) onFocus();
+      if (ie && e.keyCode == 27) { e.returnValue = false; }
+      if (pollingFast) { if (readInput()) pollingFast = false; }
+      if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;
+      var code = e_prop(e, "keyCode");
+      // IE does strange things with escape.
+      setShift(code == 16 || e_prop(e, "shiftKey"));
+      // First give onKeyEvent option a chance to handle this.
+      var handled = handleKeyBinding(e);
+      if (window.opera) {
+        lastStoppedKey = handled ? code : null;
+        // Opera has no cut event... we try to at least catch the key combo
+        if (!handled && code == 88 && e_prop(e, mac ? "metaKey" : "ctrlKey"))
+          replaceSelection("");
+      }
+    }
+    function onKeyPress(e) {
+      if (pollingFast) readInput();
+      if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;
+      var keyCode = e_prop(e, "keyCode"), charCode = e_prop(e, "charCode");
+      if (window.opera && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
+      if (((window.opera && !e.which) || khtml) && handleKeyBinding(e)) return;
+      var ch = String.fromCharCode(charCode == null ? keyCode : charCode);
+      if (options.electricChars && mode.electricChars && options.smartIndent && !options.readOnly) {
+        if (mode.electricChars.indexOf(ch) > -1)
+          setTimeout(operation(function() {indentLine(sel.to.line, "smart");}), 75);
+      }
+      if (handleCharBinding(e, ch)) return;
+      fastPoll();
+    }
+    function onKeyUp(e) {
+      if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;
+      if (e_prop(e, "keyCode") == 16) shiftSelecting = null;
+    }
+
+    function onFocus() {
+      if (options.readOnly == "nocursor") return;
+      if (!focused) {
+        if (options.onFocus) options.onFocus(instance);
+        focused = true;
+        if (wrapper.className.search(/\bCodeMirror-focused\b/) == -1)
+          wrapper.className += " CodeMirror-focused";
+        if (!leaveInputAlone) resetInput(true);
+      }
+      slowPoll();
+      restartBlink();
+    }
+    function onBlur() {
+      if (focused) {
+        if (options.onBlur) options.onBlur(instance);
+        focused = false;
+        if (bracketHighlighted)
+          operation(function(){
+            if (bracketHighlighted) { bracketHighlighted(); bracketHighlighted = null; }
+          })();
+        wrapper.className = wrapper.className.replace(" CodeMirror-focused", "");
+      }
+      clearInterval(blinker);
+      setTimeout(function() {if (!focused) shiftSelecting = null;}, 150);
+    }
+
+    // Replace the range from from to to by the strings in newText.
+    // Afterwards, set the selection to selFrom, selTo.
+    function updateLines(from, to, newText, selFrom, selTo) {
+      if (suppressEdits) return;
+      if (history) {
+        var old = [];
+        doc.iter(from.line, to.line + 1, function(line) { old.push(line.text); });
+        history.addChange(from.line, newText.length, old);
+        while (history.done.length > options.undoDepth) history.done.shift();
+      }
+      updateLinesNoUndo(from, to, newText, selFrom, selTo);
+    }
+    function unredoHelper(from, to) {
+      if (!from.length) return;
+      var set = from.pop(), out = [];
+      for (var i = set.length - 1; i >= 0; i -= 1) {
+        var change = set[i];
+        var replaced = [], end = change.start + change.added;
+        doc.iter(change.start, end, function(line) { replaced.push(line.text); });
+        out.push({start: change.start, added: change.old.length, old: replaced});
+        var pos = clipPos({line: change.start + change.old.length - 1,
+                           ch: editEnd(replaced[replaced.length-1], change.old[change.old.length-1])});
+        updateLinesNoUndo({line: change.start, ch: 0}, {line: end - 1, ch: getLine(end-1).text.length}, change.old, pos, pos);
+      }
+      updateInput = true;
+      to.push(out);
+    }
+    function undo() {unredoHelper(history.done, history.undone);}
+    function redo() {unredoHelper(history.undone, history.done);}
+
+    function updateLinesNoUndo(from, to, newText, selFrom, selTo) {
+      if (suppressEdits) return;
+      var recomputeMaxLength = false, maxLineLength = maxLine.length;
+      if (!options.lineWrapping)
+        doc.iter(from.line, to.line + 1, function(line) {
+          if (line.text.length == maxLineLength) {recomputeMaxLength = true; return true;}
+        });
+      if (from.line != to.line || newText.length > 1) gutterDirty = true;
+
+      var nlines = to.line - from.line, firstLine = getLine(from.line), lastLine = getLine(to.line);
+      // First adjust the line structure, taking some care to leave highlighting intact.
+      if (from.ch == 0 && to.ch == 0 && newText[newText.length - 1] == "") {
+        // This is a whole-line replace. Treated specially to make
+        // sure line objects move the way they are supposed to.
+        var added = [], prevLine = null;
+        if (from.line) {
+          prevLine = getLine(from.line - 1);
+          prevLine.fixMarkEnds(lastLine);
+        } else lastLine.fixMarkStarts();
+        for (var i = 0, e = newText.length - 1; i < e; ++i)
+          added.push(Line.inheritMarks(newText[i], prevLine));
+        if (nlines) doc.remove(from.line, nlines, callbacks);
+        if (added.length) doc.insert(from.line, added);
+      } else if (firstLine == lastLine) {
+        if (newText.length == 1)
+          firstLine.replace(from.ch, to.ch, newText[0]);
+        else {
+          lastLine = firstLine.split(to.ch, newText[newText.length-1]);
+          firstLine.replace(from.ch, null, newText[0]);
+          firstLine.fixMarkEnds(lastLine);
+          var added = [];
+          for (var i = 1, e = newText.length - 1; i < e; ++i)
+            added.push(Line.inheritMarks(newText[i], firstLine));
+          added.push(lastLine);
+          doc.insert(from.line + 1, added);
+        }
+      } else if (newText.length == 1) {
+        firstLine.replace(from.ch, null, newText[0]);
+        lastLine.replace(null, to.ch, "");
+        firstLine.append(lastLine);
+        doc.remove(from.line + 1, nlines, callbacks);
+      } else {
+        var added = [];
+        firstLine.replace(from.ch, null, newText[0]);
+        lastLine.replace(null, to.ch, newText[newText.length-1]);
+        firstLine.fixMarkEnds(lastLine);
+        for (var i = 1, e = newText.length - 1; i < e; ++i)
+          added.push(Line.inheritMarks(newText[i], firstLine));
+        if (nlines > 1) doc.remove(from.line + 1, nlines - 1, callbacks);
+        doc.insert(from.line + 1, added);
+      }
+      if (options.lineWrapping) {
+        var perLine = Math.max(5, scroller.clientWidth / charWidth() - 3);
+        doc.iter(from.line, from.line + newText.length, function(line) {
+          if (line.hidden) return;
+          var guess = Math.ceil(line.text.length / perLine) || 1;
+          if (guess != line.height) updateLineHeight(line, guess);
+        });
+      } else {
+        doc.iter(from.line, from.line + newText.length, function(line) {
+          var l = line.text;
+          if (l.length > maxLineLength) {
+            maxLine = l; maxLineLength = l.length; maxWidth = null;
+            recomputeMaxLength = false;
+          }
+        });
+        if (recomputeMaxLength) {
+          maxLineLength = 0; maxLine = ""; maxWidth = null;
+          doc.iter(0, doc.size, function(line) {
+            var l = line.text;
+            if (l.length > maxLineLength) {
+              maxLineLength = l.length; maxLine = l;
+            }
+          });
+        }
+      }
+
+      // Add these lines to the work array, so that they will be
+      // highlighted. Adjust work lines if lines were added/removed.
+      var newWork = [], lendiff = newText.length - nlines - 1;
+      for (var i = 0, l = work.length; i < l; ++i) {
+        var task = work[i];
+        if (task < from.line) newWork.push(task);
+        else if (task > to.line) newWork.push(task + lendiff);
+      }
+      var hlEnd = from.line + Math.min(newText.length, 500);
+      highlightLines(from.line, hlEnd);
+      newWork.push(hlEnd);
+      work = newWork;
+      startWorker(100);
+      // Remember that these lines changed, for updating the display
+      changes.push({from: from.line, to: to.line + 1, diff: lendiff});
+      var changeObj = {from: from, to: to, text: newText};
+      if (textChanged) {
+        for (var cur = textChanged; cur.next; cur = cur.next) {}
+        cur.next = changeObj;
+      } else textChanged = changeObj;
+
+      // Update the selection
+      function updateLine(n) {return n <= Math.min(to.line, to.line + lendiff) ? n : n + lendiff;}
+      setSelection(selFrom, selTo, updateLine(sel.from.line), updateLine(sel.to.line));
+
+      // Make sure the scroll-size div has the correct height.
+      if (scroller.clientHeight)
+        code.style.height = (doc.height * textHeight() + 2 * paddingTop()) + "px";
+    }
+
+    function replaceRange(code, from, to) {
+      from = clipPos(from);
+      if (!to) to = from; else to = clipPos(to);
+      code = splitLines(code);
+      function adjustPos(pos) {
+        if (posLess(pos, from)) return pos;
+        if (!posLess(to, pos)) return end;
+        var line = pos.line + code.length - (to.line - from.line) - 1;
+        var ch = pos.ch;
+        if (pos.line == to.line)
+          ch += code[code.length-1].length - (to.ch - (to.line == from.line ? from.ch : 0));
+        return {line: line, ch: ch};
+      }
+      var end;
+      replaceRange1(code, from, to, function(end1) {
+        end = end1;
+        return {from: adjustPos(sel.from), to: adjustPos(sel.to)};
+      });
+      return end;
+    }
+    function replaceSelection(code, collapse) {
+      replaceRange1(splitLines(code), sel.from, sel.to, function(end) {
+        if (collapse == "end") return {from: end, to: end};
+        else if (collapse == "start") return {from: sel.from, to: sel.from};
+        else return {from: sel.from, to: end};
+      });
+    }
+    function replaceRange1(code, from, to, computeSel) {
+      var endch = code.length == 1 ? code[0].length + from.ch : code[code.length-1].length;
+      var newSel = computeSel({line: from.line + code.length - 1, ch: endch});
+      updateLines(from, to, code, newSel.from, newSel.to);
+    }
+
+    function getRange(from, to) {
+      var l1 = from.line, l2 = to.line;
+      if (l1 == l2) return getLine(l1).text.slice(from.ch, to.ch);
+      var code = [getLine(l1).text.slice(from.ch)];
+      doc.iter(l1 + 1, l2, function(line) { code.push(line.text); });
+      code.push(getLine(l2).text.slice(0, to.ch));
+      return code.join("\n");
+    }
+    function getSelection() {
+      return getRange(sel.from, sel.to);
+    }
+
+    var pollingFast = false; // Ensures slowPoll doesn't cancel fastPoll
+    function slowPoll() {
+      if (pollingFast) return;
+      poll.set(options.pollInterval, function() {
+        startOperation();
+        readInput();
+        if (focused) slowPoll();
+        endOperation();
+      });
+    }
+    function fastPoll() {
+      var missed = false;
+      pollingFast = true;
+      function p() {
+        startOperation();
+        var changed = readInput();
+        if (!changed && !missed) {missed = true; poll.set(60, p);}
+        else {pollingFast = false; slowPoll();}
+        endOperation();
+      }
+      poll.set(20, p);
+    }
+
+    // Previnput is a hack to work with IME. If we reset the textarea
+    // on every change, that breaks IME. So we look for changes
+    // compared to the previous content instead. (Modern browsers have
+    // events that indicate IME taking place, but these are not widely
+    // supported or compatible enough yet to rely on.)
+    var prevInput = "";
+    function readInput() {
+      if (leaveInputAlone || !focused || hasSelection(input) || options.readOnly) return false;
+      var text = input.value;
+      if (text == prevInput) return false;
+      shiftSelecting = null;
+      var same = 0, l = Math.min(prevInput.length, text.length);
+      while (same < l && prevInput[same] == text[same]) ++same;
+      if (same < prevInput.length)
+        sel.from = {line: sel.from.line, ch: sel.from.ch - (prevInput.length - same)};
+      else if (overwrite && posEq(sel.from, sel.to))
+        sel.to = {line: sel.to.line, ch: Math.min(getLine(sel.to.line).text.length, sel.to.ch + (text.length - same))};
+      replaceSelection(text.slice(same), "end");
+      prevInput = text;
+      return true;
+    }
+    function resetInput(user) {
+      if (!posEq(sel.from, sel.to)) {
+        prevInput = "";
+        input.value = getSelection();
+        selectInput(input);
+      } else if (user) prevInput = input.value = "";
+    }
+
+    function focusInput() {
+      if (options.readOnly != "nocursor") input.focus();
+    }
+
+    function scrollEditorIntoView() {
+      if (!cursor.getBoundingClientRect) return;
+      var rect = cursor.getBoundingClientRect();
+      // IE returns bogus coordinates when the instance sits inside of an iframe and the cursor is hidden
+      if (ie && rect.top == rect.bottom) return;
+      var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
+      if (rect.top < 0 || rect.bottom > winH) cursor.scrollIntoView();
+    }
+    function scrollCursorIntoView() {
+      var cursor = localCoords(sel.inverted ? sel.from : sel.to);
+      var x = options.lineWrapping ? Math.min(cursor.x, lineSpace.offsetWidth) : cursor.x;
+      return scrollIntoView(x, cursor.y, x, cursor.yBot);
+    }
+    function scrollIntoView(x1, y1, x2, y2) {
+      var pl = paddingLeft(), pt = paddingTop();
+      y1 += pt; y2 += pt; x1 += pl; x2 += pl;
+      var screen = scroller.clientHeight, screentop = scroller.scrollTop, scrolled = false, result = true;
+      if (y1 < screentop) {scroller.scrollTop = Math.max(0, y1); scrolled = true;}
+      else if (y2 > screentop + screen) {scroller.scrollTop = y2 - screen; scrolled = true;}
+
+      var screenw = scroller.clientWidth, screenleft = scroller.scrollLeft;
+      var gutterw = options.fixedGutter ? gutter.clientWidth : 0;
+      var atLeft = x1 < gutterw + pl + 10;
+      if (x1 < screenleft + gutterw || atLeft) {
+        if (atLeft) x1 = 0;
+        scroller.scrollLeft = Math.max(0, x1 - 10 - gutterw);
+        scrolled = true;
+      }
+      else if (x2 > screenw + screenleft - 3) {
+        scroller.scrollLeft = x2 + 10 - screenw;
+        scrolled = true;
+        if (x2 > code.clientWidth) result = false;
+      }
+      if (scrolled && options.onScroll) options.onScroll(instance);
+      return result;
+    }
+
+    function visibleLines() {
+      var lh = textHeight(), top = scroller.scrollTop - paddingTop();
+      var fromHeight = Math.max(0, Math.floor(top / lh));
+      var toHeight = Math.ceil((top + scroller.clientHeight) / lh);
+      return {from: lineAtHeight(doc, fromHeight),
+              to: lineAtHeight(doc, toHeight)};
+    }
+    // Uses a set of changes plus the current scroll position to
+    // determine which DOM updates have to be made, and makes the
+    // updates.
+    function updateDisplay(changes, suppressCallback) {
+      if (!scroller.clientWidth) {
+        showingFrom = showingTo = displayOffset = 0;
+        return;
+      }
+      // Compute the new visible window
+      var visible = visibleLines();
+      // Bail out if the visible area is already rendered and nothing changed.
+      if (changes !== true && changes.length == 0 && visible.from > showingFrom && visible.to < showingTo) return;
+      var from = Math.max(visible.from - 100, 0), to = Math.min(doc.size, visible.to + 100);
+      if (showingFrom < from && from - showingFrom < 20) from = showingFrom;
+      if (showingTo > to && showingTo - to < 20) to = Math.min(doc.size, showingTo);
+
+      // Create a range of theoretically intact lines, and punch holes
+      // in that using the change info.
+      var intact = changes === true ? [] :
+        computeIntact([{from: showingFrom, to: showingTo, domStart: 0}], changes);
+      // Clip off the parts that won't be visible
+      var intactLines = 0;
+      for (var i = 0; i < intact.length; ++i) {
+        var range = intact[i];
+        if (range.from < from) {range.domStart += (from - range.from); range.from = from;}
+        if (range.to > to) range.to = to;
+        if (range.from >= range.to) intact.splice(i--, 1);
+        else intactLines += range.to - range.from;
+      }
+      if (intactLines == to - from && from == showingFrom && to == showingTo) return;
+      intact.sort(function(a, b) {return a.domStart - b.domStart;});
+
+      var th = textHeight(), gutterDisplay = gutter.style.display;
+      lineDiv.style.display = "none";
+      patchDisplay(from, to, intact);
+      lineDiv.style.display = gutter.style.display = "";
+
+      // Position the mover div to align with the lines it's supposed
+      // to be showing (which will cover the visible display)
+      var different = from != showingFrom || to != showingTo || lastSizeC != scroller.clientHeight + th;
+      // This is just a bogus formula that detects when the editor is
+      // resized or the font size changes.
+      if (different) lastSizeC = scroller.clientHeight + th;
+      showingFrom = from; showingTo = to;
+      displayOffset = heightAtLine(doc, from);
+      mover.style.top = (displayOffset * th) + "px";
+      if (scroller.clientHeight)
+        code.style.height = (doc.height * th + 2 * paddingTop()) + "px";
+
+      // Since this is all rather error prone, it is honoured with the
+      // only assertion in the whole file.
+      if (lineDiv.childNodes.length != showingTo - showingFrom)
+        throw new Error("BAD PATCH! " + JSON.stringify(intact) + " size=" + (showingTo - showingFrom) +
+                        " nodes=" + lineDiv.childNodes.length);
+
+      function checkHeights() {
+        maxWidth = scroller.clientWidth;
+        var curNode = lineDiv.firstChild, heightChanged = false;
+        doc.iter(showingFrom, showingTo, function(line) {
+          if (!line.hidden) {
+            var height = Math.round(curNode.offsetHeight / th) || 1;
+            if (line.height != height) {
+              updateLineHeight(line, height);
+              gutterDirty = heightChanged = true;
+            }
+          }
+          curNode = curNode.nextSibling;
+        });
+        if (heightChanged)
+          code.style.height = (doc.height * th + 2 * paddingTop()) + "px";
+        return heightChanged;
+      }
+
+      if (options.lineWrapping) {
+        checkHeights();
+      } else {
+        if (maxWidth == null) maxWidth = stringWidth(maxLine);
+        if (maxWidth > scroller.clientWidth) {
+          lineSpace.style.width = maxWidth + "px";
+          // Needed to prevent odd wrapping/hiding of widgets placed in here.
+          code.style.width = "";
+          code.style.width = scroller.scrollWidth + "px";
+        } else {
+          lineSpace.style.width = code.style.width = "";
+        }
+      }
+
+      gutter.style.display = gutterDisplay;
+      if (different || gutterDirty) {
+        // If the gutter grew in size, re-check heights. If those changed, re-draw gutter.
+        updateGutter() && options.lineWrapping && checkHeights() && updateGutter();
+      }
+      updateSelection();
+      if (!suppressCallback && options.onUpdate) options.onUpdate(instance);
+      return true;
+    }
+
+    function computeIntact(intact, changes) {
+      for (var i = 0, l = changes.length || 0; i < l; ++i) {
+        var change = changes[i], intact2 = [], diff = change.diff || 0;
+        for (var j = 0, l2 = intact.length; j < l2; ++j) {
+          var range = intact[j];
+          if (change.to <= range.from && change.diff)
+            intact2.push({from: range.from + diff, to: range.to + diff,
+                          domStart: range.domStart});
+          else if (change.to <= range.from || change.from >= range.to)
+            intact2.push(range);
+          else {
+            if (change.from > range.from)
+              intact2.push({from: range.from, to: change.from, domStart: range.domStart});
+            if (change.to < range.to)
+              intact2.push({from: change.to + diff, to: range.to + diff,
+                            domStart: range.domStart + (change.to - range.from)});
+          }
+        }
+        intact = intact2;
+      }
+      return intact;
+    }
+
+    function patchDisplay(from, to, intact) {
+      // The first pass removes the DOM nodes that aren't intact.
+      if (!intact.length) lineDiv.innerHTML = "";
+      else {
+        function killNode(node) {
+          var tmp = node.nextSibling;
+          node.parentNode.removeChild(node);
+          return tmp;
+        }
+        var domPos = 0, curNode = lineDiv.firstChild, n;
+        for (var i = 0; i < intact.length; ++i) {
+          var cur = intact[i];
+          while (cur.domStart > domPos) {curNode = killNode(curNode); domPos++;}
+          for (var j = 0, e = cur.to - cur.from; j < e; ++j) {curNode = curNode.nextSibling; domPos++;}
+        }
+        while (curNode) curNode = killNode(curNode);
+      }
+      // This pass fills in the lines that actually changed.
+      var nextIntact = intact.shift(), curNode = lineDiv.firstChild, j = from;
+      var scratch = document.createElement("div");
+      doc.iter(from, to, function(line) {
+        if (nextIntact && nextIntact.to == j) nextIntact = intact.shift();
+        if (!nextIntact || nextIntact.from > j) {
+          if (line.hidden) var html = scratch.innerHTML = "<pre></pre>";
+          else {
+            var html = '<pre' + (line.className ? ' class="' + line.className + '"' : '') + '>'
+              + line.getHTML(makeTab) + '</pre>';
+            // Kludge to make sure the styled element lies behind the selection (by z-index)
+            if (line.bgClassName)
+              html = '<div style="position: relative"><pre class="' + line.bgClassName +
+              '" style="position: absolute; left: 0; right: 0; top: 0; bottom: 0; z-index: -2">&#160;</pre>' + html + "</div>";
+          }
+          scratch.innerHTML = html;
+          lineDiv.insertBefore(scratch.firstChild, curNode);
+        } else {
+          curNode = curNode.nextSibling;
+        }
+        ++j;
+      });
+    }
+
+    function updateGutter() {
+      if (!options.gutter && !options.lineNumbers) return;
+      var hText = mover.offsetHeight, hEditor = scroller.clientHeight;
+      gutter.style.height = (hText - hEditor < 2 ? hEditor : hText) + "px";
+      var html = [], i = showingFrom, normalNode;
+      doc.iter(showingFrom, Math.max(showingTo, showingFrom + 1), function(line) {
+        if (line.hidden) {
+          html.push("<pre></pre>");
+        } else {
+          var marker = line.gutterMarker;
+          var text = options.lineNumbers ? i + options.firstLineNumber : null;
+          if (marker && marker.text)
+            text = marker.text.replace("%N%", text != null ? text : "");
+          else if (text == null)
+            text = "\u00a0";
+          html.push((marker && marker.style ? '<pre class="' + marker.style + '">' : "<pre>"), text);
+          for (var j = 1; j < line.height; ++j) html.push("<br/>&#160;");
+          html.push("</pre>");
+          if (!marker) normalNode = i;
+        }
+        ++i;
+      });
+      gutter.style.display = "none";
+      gutterText.innerHTML = html.join("");
+      // Make sure scrolling doesn't cause number gutter size to pop
+      if (normalNode != null) {
+        var node = gutterText.childNodes[normalNode - showingFrom];
+        var minwidth = String(doc.size).length, val = eltText(node), pad = "";
+        while (val.length + pad.length < minwidth) pad += "\u00a0";
+        if (pad) node.insertBefore(document.createTextNode(pad), node.firstChild);
+      }
+      gutter.style.display = "";
+      var resized = Math.abs((parseInt(lineSpace.style.marginLeft) || 0) - gutter.offsetWidth) > 2;
+      lineSpace.style.marginLeft = gutter.offsetWidth + "px";
+      gutterDirty = false;
+      return resized;
+    }
+    function updateSelection() {
+      var collapsed = posEq(sel.from, sel.to);
+      var fromPos = localCoords(sel.from, true);
+      var toPos = collapsed ? fromPos : localCoords(sel.to, true);
+      var headPos = sel.inverted ? fromPos : toPos, th = textHeight();
+      var wrapOff = eltOffset(wrapper), lineOff = eltOffset(lineDiv);
+      inputDiv.style.top = Math.max(0, Math.min(scroller.offsetHeight, headPos.y + lineOff.top - wrapOff.top)) + "px";
+      inputDiv.style.left = Math.max(0, Math.min(scroller.offsetWidth, headPos.x + lineOff.left - wrapOff.left)) + "px";
+      if (collapsed) {
+        cursor.style.top = headPos.y + "px";
+        cursor.style.left = (options.lineWrapping ? Math.min(headPos.x, lineSpace.offsetWidth) : headPos.x) + "px";
+        cursor.style.display = "";
+        selectionDiv.style.display = "none";
+      } else {
+        var sameLine = fromPos.y == toPos.y, html = "";
+        var clientWidth = lineSpace.clientWidth || lineSpace.offsetWidth;
+        var clientHeight = lineSpace.clientHeight || lineSpace.offsetHeight;
+        function add(left, top, right, height) {
+          var rstyle = quirksMode ? "width: " + (!right ? clientWidth : clientWidth - right - left) + "px"
+                                  : "right: " + right + "px";
+          html += '<div class="CodeMirror-selected" style="position: absolute; left: ' + left +
+            'px; top: ' + top + 'px; ' + rstyle + '; height: ' + height + 'px"></div>';
+        }
+        if (sel.from.ch && fromPos.y >= 0) {
+          var right = sameLine ? clientWidth - toPos.x : 0;
+          add(fromPos.x, fromPos.y, right, th);
+        }
+        var middleStart = Math.max(0, fromPos.y + (sel.from.ch ? th : 0));
+        var middleHeight = Math.min(toPos.y, clientHeight) - middleStart;
+        if (middleHeight > 0.2 * th)
+          add(0, middleStart, 0, middleHeight);
+        if ((!sameLine || !sel.from.ch) && toPos.y < clientHeight - .5 * th)
+          add(0, toPos.y, clientWidth - toPos.x, th);
+        selectionDiv.innerHTML = html;
+        cursor.style.display = "none";
+        selectionDiv.style.display = "";
+      }
+    return cursor.style.top;
+    }
+
+    function setShift(val) {
+      if (val) shiftSelecting = shiftSelecting || (sel.inverted ? sel.to : sel.from);
+      else shiftSelecting = null;
+    }
+    function setSelectionUser(from, to) {
+      var sh = shiftSelecting && clipPos(shiftSelecting);
+      if (sh) {
+        if (posLess(sh, from)) from = sh;
+        else if (posLess(to, sh)) to = sh;
+      }
+      setSelection(from, to);
+      userSelChange = true;
+    }
+    // Update the selection. Last two args are only used by
+    // updateLines, since they have to be expressed in the line
+    // numbers before the update.
+    function setSelection(from, to, oldFrom, oldTo) {
+      goalColumn = null;
+      if (oldFrom == null) {oldFrom = sel.from.line; oldTo = sel.to.line;}
+      if (posEq(sel.from, from) && posEq(sel.to, to)) return;
+      if (posLess(to, from)) {var tmp = to; to = from; from = tmp;}
+
+      // Skip over hidden lines.
+      if (from.line != oldFrom) {
+        var from1 = skipHidden(from, oldFrom, sel.from.ch);
+        // If there is no non-hidden line left, force visibility on current line
+        if (!from1) setLineHidden(from.line, false);
+        else from = from1;
+      }
+      if (to.line != oldTo) to = skipHidden(to, oldTo, sel.to.ch);
+
+      if (posEq(from, to)) sel.inverted = false;
+      else if (posEq(from, sel.to)) sel.inverted = false;
+      else if (posEq(to, sel.from)) sel.inverted = true;
+
+      if (options.autoClearEmptyLines && posEq(sel.from, sel.to)) {
+        var head = sel.inverted ? from : to;
+        if (head.line != sel.from.line && sel.from.line < doc.size) {
+          var oldLine = getLine(sel.from.line);
+          if (/^\s+$/.test(oldLine.text))
+            setTimeout(operation(function() {
+              if (oldLine.parent && /^\s+$/.test(oldLine.text)) {
+                var no = lineNo(oldLine);
+                replaceRange("", {line: no, ch: 0}, {line: no, ch: oldLine.text.length});
+              }
+            }, 10));
+        }
+      }
+
+      sel.from = from; sel.to = to;
+      selectionChanged = true;
+    }
+    function skipHidden(pos, oldLine, oldCh) {
+      function getNonHidden(dir) {
+        var lNo = pos.line + dir, end = dir == 1 ? doc.size : -1;
+        while (lNo != end) {
+          var line = getLine(lNo);
+          if (!line.hidden) {
+            var ch = pos.ch;
+            if (toEnd || ch > oldCh || ch > line.text.length) ch = line.text.length;
+            return {line: lNo, ch: ch};
+          }
+          lNo += dir;
+        }
+      }
+      var line = getLine(pos.line);
+      var toEnd = pos.ch == line.text.length && pos.ch != oldCh;
+      if (!line.hidden) return pos;
+      if (pos.line >= oldLine) return getNonHidden(1) || getNonHidden(-1);
+      else return getNonHidden(-1) || getNonHidden(1);
+    }
+    function setCursor(line, ch, user) {
+      var pos = clipPos({line: line, ch: ch || 0});
+      (user ? setSelectionUser : setSelection)(pos, pos);
+    }
+
+    function clipLine(n) {return Math.max(0, Math.min(n, doc.size-1));}
+    function clipPos(pos) {
+      if (pos.line < 0) return {line: 0, ch: 0};
+      if (pos.line >= doc.size) return {line: doc.size-1, ch: getLine(doc.size-1).text.length};
+      var ch = pos.ch, linelen = getLine(pos.line).text.length;
+      if (ch == null || ch > linelen) return {line: pos.line, ch: linelen};
+      else if (ch < 0) return {line: pos.line, ch: 0};
+      else return pos;
+    }
+
+    function findPosH(dir, unit) {
+      var end = sel.inverted ? sel.from : sel.to, line = end.line, ch = end.ch;
+      var lineObj = getLine(line);
+      function findNextLine() {
+        for (var l = line + dir, e = dir < 0 ? -1 : doc.size; l != e; l += dir) {
+          var lo = getLine(l);
+          if (!lo.hidden) { line = l; lineObj = lo; return true; }
+        }
+      }
+      function moveOnce(boundToLine) {
+        if (ch == (dir < 0 ? 0 : lineObj.text.length)) {
+          if (!boundToLine && findNextLine()) ch = dir < 0 ? lineObj.text.length : 0;
+          else return false;
+        } else ch += dir;
+        return true;
+      }
+      if (unit == "char") moveOnce();
+      else if (unit == "column") moveOnce(true);
+      else if (unit == "word") {
+        var sawWord = false;
+        for (;;) {
+          if (dir < 0) if (!moveOnce()) break;
+          if (isWordChar(lineObj.text.charAt(ch))) sawWord = true;
+          else if (sawWord) {if (dir < 0) {dir = 1; moveOnce();} break;}
+          if (dir > 0) if (!moveOnce()) break;
+        }
+      }
+      return {line: line, ch: ch};
+    }
+    function moveH(dir, unit) {
+      var pos = dir < 0 ? sel.from : sel.to;
+      if (shiftSelecting || posEq(sel.from, sel.to)) pos = findPosH(dir, unit);
+      setCursor(pos.line, pos.ch, true);
+    }
+    function deleteH(dir, unit) {
+      if (!posEq(sel.from, sel.to)) replaceRange("", sel.from, sel.to);
+      else if (dir < 0) replaceRange("", findPosH(dir, unit), sel.to);
+      else replaceRange("", sel.from, findPosH(dir, unit));
+      userSelChange = true;
+    }
+    var goalColumn = null;
+    function moveV(dir, unit) {
+      var dist = 0, pos = localCoords(sel.inverted ? sel.from : sel.to, true);
+      if (goalColumn != null) pos.x = goalColumn;
+      if (unit == "page") dist = Math.min(scroller.clientHeight, window.innerHeight || document.documentElement.clientHeight);
+      else if (unit == "line") dist = textHeight();
+      var target = coordsChar(pos.x, pos.y + dist * dir + 2);
+      if (unit == "page") scroller.scrollTop += localCoords(target, true).y - pos.y;
+      setCursor(target.line, target.ch, true);
+      goalColumn = pos.x;
+    }
+
+    function selectWordAt(pos) {
+      var line = getLine(pos.line).text;
+      var start = pos.ch, end = pos.ch;
+      while (start > 0 && isWordChar(line.charAt(start - 1))) --start;
+      while (end < line.length && isWordChar(line.charAt(end))) ++end;
+      setSelectionUser({line: pos.line, ch: start}, {line: pos.line, ch: end});
+    }
+    function selectLine(line) {
+      setSelectionUser({line: line, ch: 0}, clipPos({line: line + 1, ch: 0}));
+    }
+    function indentSelected(mode) {
+      if (posEq(sel.from, sel.to)) return indentLine(sel.from.line, mode);
+      var e = sel.to.line - (sel.to.ch ? 0 : 1);
+      for (var i = sel.from.line; i <= e; ++i) indentLine(i, mode);
+    }
+
+    function indentLine(n, how) {
+      if (!how) how = "add";
+      if (how == "smart") {
+        if (!mode.indent) how = "prev";
+        else var state = getStateBefore(n);
+      }
+
+      var line = getLine(n), curSpace = line.indentation(options.tabSize),
+          curSpaceString = line.text.match(/^\s*/)[0], indentation;
+      if (how == "prev") {
+        if (n) indentation = getLine(n-1).indentation(options.tabSize);
+        else indentation = 0;
+      }
+      else if (how == "smart") indentation = mode.indent(state, line.text.slice(curSpaceString.length), line.text);
+      else if (how == "add") indentation = curSpace + options.indentUnit;
+      else if (how == "subtract") indentation = curSpace - options.indentUnit;
+      indentation = Math.max(0, indentation);
+      var diff = indentation - curSpace;
+
+      if (!diff) {
+        if (sel.from.line != n && sel.to.line != n) return;
+        var indentString = curSpaceString;
+      }
+      else {
+        var indentString = "", pos = 0;
+        if (options.indentWithTabs)
+          for (var i = Math.floor(indentation / options.tabSize); i; --i) {pos += options.tabSize; indentString += "\t";}
+        while (pos < indentation) {++pos; indentString += " ";}
+      }
+
+      replaceRange(indentString, {line: n, ch: 0}, {line: n, ch: curSpaceString.length});
+    }
+
+    function loadMode() {
+      mode = CodeMirror.getMode(options, options.mode);
+      doc.iter(0, doc.size, function(line) { line.stateAfter = null; });
+      work = [0];
+      startWorker();
+    }
+    function gutterChanged() {
+      var visible = options.gutter || options.lineNumbers;
+      gutter.style.display = visible ? "" : "none";
+      if (visible) gutterDirty = true;
+      else lineDiv.parentNode.style.marginLeft = 0;
+    }
+    function wrappingChanged(from, to) {
+      if (options.lineWrapping) {
+        wrapper.className += " CodeMirror-wrap";
+        var perLine = scroller.clientWidth / charWidth() - 3;
+        doc.iter(0, doc.size, function(line) {
+          if (line.hidden) return;
+          var guess = Math.ceil(line.text.length / perLine) || 1;
+          if (guess != 1) updateLineHeight(line, guess);
+        });
+        lineSpace.style.width = code.style.width = "";
+      } else {
+        wrapper.className = wrapper.className.replace(" CodeMirror-wrap", "");
+        maxWidth = null; maxLine = "";
+        doc.iter(0, doc.size, function(line) {
+          if (line.height != 1 && !line.hidden) updateLineHeight(line, 1);
+          if (line.text.length > maxLine.length) maxLine = line.text;
+        });
+      }
+      changes.push({from: 0, to: doc.size});
+    }
+    function makeTab(col) {
+      var w = options.tabSize - col % options.tabSize, cached = tabCache[w];
+      if (cached) return cached;
+      for (var str = '<span class="cm-tab">', i = 0; i < w; ++i) str += " ";
+      return (tabCache[w] = {html: str + "</span>", width: w});
+    }
+    function themeChanged() {
+      scroller.className = scroller.className.replace(/\s*cm-s-\S+/g, "") +
+        options.theme.replace(/(^|\s)\s*/g, " cm-s-");
+    }
+    function keyMapChanged() {
+      var style = keyMap[options.keyMap].style;
+      wrapper.className = wrapper.className.replace(/\s*cm-keymap-\S+/g, "") +
+        (style ? " cm-keymap-" + style : "");
+    }
+
+    function TextMarker() { this.set = []; }
+    TextMarker.prototype.clear = operation(function() {
+      var min = Infinity, max = -Infinity;
+      for (var i = 0, e = this.set.length; i < e; ++i) {
+        var line = this.set[i], mk = line.marked;
+        if (!mk || !line.parent) continue;
+        var lineN = lineNo(line);
+        min = Math.min(min, lineN); max = Math.max(max, lineN);
+        for (var j = 0; j < mk.length; ++j)
+          if (mk[j].marker == this) mk.splice(j--, 1);
+      }
+      if (min != Infinity)
+        changes.push({from: min, to: max + 1});
+    });
+    TextMarker.prototype.find = function() {
+      var from, to;
+      for (var i = 0, e = this.set.length; i < e; ++i) {
+        var line = this.set[i], mk = line.marked;
+        for (var j = 0; j < mk.length; ++j) {
+          var mark = mk[j];
+          if (mark.marker == this) {
+            if (mark.from != null || mark.to != null) {
+              var found = lineNo(line);
+              if (found != null) {
+                if (mark.from != null) from = {line: found, ch: mark.from};
+                if (mark.to != null) to = {line: found, ch: mark.to};
+              }
+            }
+          }
+        }
+      }
+      return {from: from, to: to};
+    };
+
+    function markText(from, to, className) {
+      from = clipPos(from); to = clipPos(to);
+      var tm = new TextMarker();
+      if (!posLess(from, to)) return tm;
+      function add(line, from, to, className) {
+        getLine(line).addMark(new MarkedText(from, to, className, tm));
+      }
+      if (from.line == to.line) add(from.line, from.ch, to.ch, className);
+      else {
+        add(from.line, from.ch, null, className);
+        for (var i = from.line + 1, e = to.line; i < e; ++i)
+          add(i, null, null, className);
+        add(to.line, null, to.ch, className);
+      }
+      changes.push({from: from.line, to: to.line + 1});
+      return tm;
+    }
+
+    function setBookmark(pos) {
+      pos = clipPos(pos);
+      var bm = new Bookmark(pos.ch);
+      getLine(pos.line).addMark(bm);
+      return bm;
+    }
+
+    function findMarksAt(pos) {
+      pos = clipPos(pos);
+      var markers = [], marked = getLine(pos.line).marked;
+      if (!marked) return markers;
+      for (var i = 0, e = marked.length; i < e; ++i) {
+        var m = marked[i];
+        if ((m.from == null || m.from <= pos.ch) &&
+            (m.to == null || m.to >= pos.ch))
+          markers.push(m.marker || m);
+      }
+      return markers;
+    }
+
+    function addGutterMarker(line, text, className) {
+      if (typeof line == "number") line = getLine(clipLine(line));
+      line.gutterMarker = {text: text, style: className};
+      gutterDirty = true;
+      return line;
+    }
+    function removeGutterMarker(line) {
+      if (typeof line == "number") line = getLine(clipLine(line));
+      line.gutterMarker = null;
+      gutterDirty = true;
+    }
+
+    function changeLine(handle, op) {
+      var no = handle, line = handle;
+      if (typeof handle == "number") line = getLine(clipLine(handle));
+      else no = lineNo(handle);
+      if (no == null) return null;
+      if (op(line, no)) changes.push({from: no, to: no + 1});
+      else return null;
+      return line;
+    }
+    function setLineClass(handle, className, bgClassName) {
+      return changeLine(handle, function(line) {
+        if (line.className != className || line.bgClassName != bgClassName) {
+          line.className = className;
+          line.bgClassName = bgClassName;
+          return true;
+        }
+      });
+    }
+    function setLineHidden(handle, hidden) {
+      return changeLine(handle, function(line, no) {
+        if (line.hidden != hidden) {
+          line.hidden = hidden;
+          updateLineHeight(line, hidden ? 0 : 1);
+          var fline = sel.from.line, tline = sel.to.line;
+          if (hidden && (fline == no || tline == no)) {
+            var from = fline == no ? skipHidden({line: fline, ch: 0}, fline, 0) : sel.from;
+            var to = tline == no ? skipHidden({line: tline, ch: 0}, tline, 0) : sel.to;
+            // Can't hide the last visible line, we'd have no place to put the cursor
+            if (!to) return;
+            setSelection(from, to);
+          }
+          return (gutterDirty = true);
+        }
+      });
+    }
+	function getLineNumber(line) {
+		return line;
+}
+
+    function lineInfo(line) {
+      if (typeof line == "number") {
+        if (!isLine(line)) return null;
+        var n = line;
+        line = getLine(line);
+        if (!line) return null;
+      }
+      else {
+        var n = lineNo(line);
+        if (n == null) return null;
+      }
+      var marker = line.gutterMarker;
+      return {line: n, handle: line, text: line.text, markerText: marker && marker.text,
+              markerClass: marker && marker.style, lineClass: line.className, bgClass: line.bgClassName};
+    }
+
+    function stringWidth(str) {
+      measure.innerHTML = "<pre><span>x</span></pre>";
+      measure.firstChild.firstChild.firstChild.nodeValue = str;
+      return measure.firstChild.firstChild.offsetWidth || 10;
+    }
+    // These are used to go from pixel positions to character
+    // positions, taking varying character widths into account.
+    function charFromX(line, x) {
+      if (x <= 0) return 0;
+      var lineObj = getLine(line), text = lineObj.text;
+      function getX(len) {
+        return measureLine(lineObj, len).left;
+      }
+      var from = 0, fromX = 0, to = text.length, toX;
+      // Guess a suitable upper bound for our search.
+      var estimated = Math.min(to, Math.ceil(x / charWidth()));
+      for (;;) {
+        var estX = getX(estimated);
+        if (estX <= x && estimated < to) estimated = Math.min(to, Math.ceil(estimated * 1.2));
+        else {toX = estX; to = estimated; break;}
+      }
+      if (x > toX) return to;
+      // Try to guess a suitable lower bound as well.
+      estimated = Math.floor(to * 0.8); estX = getX(estimated);
+      if (estX < x) {from = estimated; fromX = estX;}
+      // Do a binary search between these bounds.
+      for (;;) {
+        if (to - from <= 1) return (toX - x > x - fromX) ? from : to;
+        var middle = Math.ceil((from + to) / 2), middleX = getX(middle);
+        if (middleX > x) {to = middle; toX = middleX;}
+        else {from = middle; fromX = middleX;}
+      }
+    }
+
+    var tempId = "CodeMirror-temp-" + Math.floor(Math.random() * 0xffffff).toString(16);
+    function measureLine(line, ch) {
+      if (ch == 0) return {top: 0, left: 0};
+      var wbr = options.lineWrapping && ch < line.text.length &&
+                spanAffectsWrapping.test(line.text.slice(ch - 1, ch + 1));
+      measure.innerHTML = "<pre>" + line.getHTML(makeTab, ch, tempId, wbr) + "</pre>";
+      var elt = document.getElementById(tempId);
+      var top = elt.offsetTop, left = elt.offsetLeft;
+      // Older IEs report zero offsets for spans directly after a wrap
+      if (ie && top == 0 && left == 0) {
+        var backup = document.createElement("span");
+        backup.innerHTML = "x";
+        elt.parentNode.insertBefore(backup, elt.nextSibling);
+        top = backup.offsetTop;
+      }
+      return {top: top, left: left};
+    }
+    function localCoords(pos, inLineWrap) {
+      var x, lh = textHeight(), y = lh * (heightAtLine(doc, pos.line) - (inLineWrap ? displayOffset : 0));
+      if (pos.ch == 0) x = 0;
+      else {
+        var sp = measureLine(getLine(pos.line), pos.ch);
+        x = sp.left;
+        if (options.lineWrapping) y += Math.max(0, sp.top);
+      }
+      return {x: x, y: y, yBot: y + lh};
+    }
+    // Coords must be lineSpace-local
+    function coordsChar(x, y) {
+      if (y < 0) y = 0;
+      var th = textHeight(), cw = charWidth(), heightPos = displayOffset + Math.floor(y / th);
+      var lineNo = lineAtHeight(doc, heightPos);
+      if (lineNo >= doc.size) return {line: doc.size - 1, ch: getLine(doc.size - 1).text.length};
+      var lineObj = getLine(lineNo), text = lineObj.text;
+      var tw = options.lineWrapping, innerOff = tw ? heightPos - heightAtLine(doc, lineNo) : 0;
+      if (x <= 0 && innerOff == 0) return {line: lineNo, ch: 0};
+      function getX(len) {
+        var sp = measureLine(lineObj, len);
+        if (tw) {
+          var off = Math.round(sp.top / th);
+          return Math.max(0, sp.left + (off - innerOff) * scroller.clientWidth);
+        }
+        return sp.left;
+      }
+      var from = 0, fromX = 0, to = text.length, toX;
+      // Guess a suitable upper bound for our search.
+      var estimated = Math.min(to, Math.ceil((x + innerOff * scroller.clientWidth * .9) / cw));
+      for (;;) {
+        var estX = getX(estimated);
+        if (estX <= x && estimated < to) estimated = Math.min(to, Math.ceil(estimated * 1.2));
+        else {toX = estX; to = estimated; break;}
+      }
+      if (x > toX) return {line: lineNo, ch: to};
+      // Try to guess a suitable lower bound as well.
+      estimated = Math.floor(to * 0.8); estX = getX(estimated);
+      if (estX < x) {from = estimated; fromX = estX;}
+      // Do a binary search between these bounds.
+      for (;;) {
+        if (to - from <= 1) return {line: lineNo, ch: (toX - x > x - fromX) ? from : to};
+        var middle = Math.ceil((from + to) / 2), middleX = getX(middle);
+        if (middleX > x) {to = middle; toX = middleX;}
+        else {from = middle; fromX = middleX;}
+      }
+    }
+    function pageCoords(pos) {
+      var local = localCoords(pos, true), off = eltOffset(lineSpace);
+      return {x: off.left + local.x, y: off.top + local.y, yBot: off.top + local.yBot};
+    }
+
+    var cachedHeight, cachedHeightFor, measureText;
+    function textHeight() {
+      if (measureText == null) {
+        measureText = "<pre>";
+        for (var i = 0; i < 49; ++i) measureText += "x<br/>";
+        measureText += "x</pre>";
+      }
+      var offsetHeight = lineDiv.clientHeight;
+      if (offsetHeight == cachedHeightFor) return cachedHeight;
+      cachedHeightFor = offsetHeight;
+      measure.innerHTML = measureText;
+      cachedHeight = measure.firstChild.offsetHeight / 50 || 1;
+      measure.innerHTML = "";
+      return cachedHeight;
+    }
+    var cachedWidth, cachedWidthFor = 0;
+    function charWidth() {
+      if (scroller.clientWidth == cachedWidthFor) return cachedWidth;
+      cachedWidthFor = scroller.clientWidth;
+      return (cachedWidth = stringWidth("x"));
+    }
+    function paddingTop() {return lineSpace.offsetTop;}
+    function paddingLeft() {return lineSpace.offsetLeft;}
+
+    function posFromMouse(e, liberal) {
+      var offW = eltOffset(scroller, true), x, y;
+      // Fails unpredictably on IE[67] when mouse is dragged around quickly.
+      try { x = e.clientX; y = e.clientY; } catch (e) { return null; }
+      // This is a mess of a heuristic to try and determine whether a
+      // scroll-bar was clicked or not, and to return null if one was
+      // (and !liberal).
+      if (!liberal && (x - offW.left > scroller.clientWidth || y - offW.top > scroller.clientHeight))
+        return null;
+      var offL = eltOffset(lineSpace, true);
+      return coordsChar(x - offL.left, y - offL.top);
+    }
+    function onContextMenu(e) {
+      var pos = posFromMouse(e), scrollPos = scroller.scrollTop;
+      if (!pos || window.opera) return; // Opera is difficult.
+      if (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to))
+        operation(setCursor)(pos.line, pos.ch);
+
+      var oldCSS = input.style.cssText;
+      inputDiv.style.position = "absolute";
+      input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
+        "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: white; " +
+        "border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
+      leaveInputAlone = true;
+      var val = input.value = getSelection();
+      focusInput();
+      selectInput(input);
+      function rehide() {
+        var newVal = splitLines(input.value).join("\n");
+        if (newVal != val) operation(replaceSelection)(newVal, "end");
+        inputDiv.style.position = "relative";
+        input.style.cssText = oldCSS;
+        if (ie_lt9) scroller.scrollTop = scrollPos;
+        leaveInputAlone = false;
+        resetInput(true);
+        slowPoll();
+      }
+
+      if (gecko) {
+        e_stop(e);
+        var mouseup = connect(window, "mouseup", function() {
+          mouseup();
+          setTimeout(rehide, 20);
+        }, true);
+      } else {
+        setTimeout(rehide, 50);
+      }
+    }
+
+    // Cursor-blinking
+    function restartBlink() {
+      clearInterval(blinker);
+      var on = true;
+      cursor.style.visibility = "";
+      blinker = setInterval(function() {
+        cursor.style.visibility = (on = !on) ? "" : "hidden";
+      }, 650);
+    }
+
+    var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"};
+    function matchBrackets(autoclear) {
+      var head = sel.inverted ? sel.from : sel.to, line = getLine(head.line), pos = head.ch - 1;
+      var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)];
+      if (!match) return;
+      var ch = match.charAt(0), forward = match.charAt(1) == ">", d = forward ? 1 : -1, st = line.styles;
+      for (var off = pos + 1, i = 0, e = st.length; i < e; i+=2)
+        if ((off -= st[i].length) <= 0) {var style = st[i+1]; break;}
+
+      var stack = [line.text.charAt(pos)], re = /[(){}[\]]/;
+      function scan(line, from, to) {
+        if (!line.text) return;
+        var st = line.styles, pos = forward ? 0 : line.text.length - 1, cur;
+        for (var i = forward ? 0 : st.length - 2, e = forward ? st.length : -2; i != e; i += 2*d) {
+          var text = st[i];
+          if (st[i+1] != null && st[i+1] != style) {pos += d * text.length; continue;}
+          for (var j = forward ? 0 : text.length - 1, te = forward ? text.length : -1; j != te; j += d, pos+=d) {
+            if (pos >= from && pos < to && re.test(cur = text.charAt(j))) {
+              var match = matching[cur];
+              if (match.charAt(1) == ">" == forward) stack.push(cur);
+              else if (stack.pop() != match.charAt(0)) return {pos: pos, match: false};
+              else if (!stack.length) return {pos: pos, match: true};
+            }
+          }
+        }
+      }
+      for (var i = head.line, e = forward ? Math.min(i + 100, doc.size) : Math.max(-1, i - 100); i != e; i+=d) {
+        var line = getLine(i), first = i == head.line;
+        var found = scan(line, first && forward ? pos + 1 : 0, first && !forward ? pos : line.text.length);
+        if (found) break;
+      }
+      if (!found) found = {pos: null, match: false};
+      var style = found.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
+      var one = markText({line: head.line, ch: pos}, {line: head.line, ch: pos+1}, style),
+          two = found.pos != null && markText({line: i, ch: found.pos}, {line: i, ch: found.pos + 1}, style);
+      var clear = operation(function(){one.clear(); two && two.clear();});
+      if (autoclear) setTimeout(clear, 800);
+      else bracketHighlighted = clear;
+    }
+
+    // Finds the line to start with when starting a parse. Tries to
+    // find a line with a stateAfter, so that it can start with a
+    // valid state. If that fails, it returns the line with the
+    // smallest indentation, which tends to need the least context to
+    // parse correctly.
+    function findStartLine(n) {
+      var minindent, minline;
+      for (var search = n, lim = n - 40; search > lim; --search) {
+        if (search == 0) return 0;
+        var line = getLine(search-1);
+        if (line.stateAfter) return search;
+        var indented = line.indentation(options.tabSize);
+        if (minline == null || minindent > indented) {
+          minline = search - 1;
+          minindent = indented;
+        }
+      }
+      return minline;
+    }
+    function getStateBefore(n) {
+      var start = findStartLine(n), state = start && getLine(start-1).stateAfter;
+      if (!state) state = startState(mode);
+      else state = copyState(mode, state);
+      doc.iter(start, n, function(line) {
+        line.highlight(mode, state, options.tabSize);
+        line.stateAfter = copyState(mode, state);
+      });
+      if (start < n) changes.push({from: start, to: n});
+      if (n < doc.size && !getLine(n).stateAfter) work.push(n);
+      return state;
+    }
+    function highlightLines(start, end) {
+      var state = getStateBefore(start);
+      doc.iter(start, end, function(line) {
+        line.highlight(mode, state, options.tabSize);
+        line.stateAfter = copyState(mode, state);
+      });
+    }
+    function highlightWorker() {
+      var end = +new Date + options.workTime;
+      var foundWork = work.length;
+      while (work.length) {
+        if (!getLine(showingFrom).stateAfter) var task = showingFrom;
+        else var task = work.pop();
+        if (task >= doc.size) continue;
+        var start = findStartLine(task), state = start && getLine(start-1).stateAfter;
+        if (state) state = copyState(mode, state);
+        else state = startState(mode);
+
+        var unchanged = 0, compare = mode.compareStates, realChange = false,
+            i = start, bail = false;
+        doc.iter(i, doc.size, function(line) {
+          var hadState = line.stateAfter;
+          if (+new Date > end) {
+            work.push(i);
+            startWorker(options.workDelay);
+            if (realChange) changes.push({from: task, to: i + 1});
+            return (bail = true);
+          }
+          var changed = line.highlight(mode, state, options.tabSize);
+          if (changed) realChange = true;
+          line.stateAfter = copyState(mode, state);
+          var done = null;
+          if (compare) {
+            var same = hadState && compare(hadState, state);
+            if (same != Pass) done = !!same;
+          }
+          if (done == null) {
+            if (changed !== false || !hadState) unchanged = 0;
+            else if (++unchanged > 3 && (!mode.indent || mode.indent(hadState, "") == mode.indent(state, "")))
+              done = true;
+          }
+          if (done) return true;
+          ++i;
+        });
+        if (bail) return;
+        if (realChange) changes.push({from: task, to: i + 1});
+      }
+      if (foundWork && options.onHighlightComplete)
+        options.onHighlightComplete(instance);
+    }
+    function startWorker(time) {
+      if (!work.length) return;
+      highlight.set(time, operation(highlightWorker));
+    }
+
+    // Operations are used to wrap changes in such a way that each
+    // change won't have to update the cursor and display (which would
+    // be awkward, slow, and error-prone), but instead updates are
+    // batched and then all combined and executed at once.
+    function startOperation() {
+      updateInput = userSelChange = textChanged = null;
+      changes = []; selectionChanged = false; callbacks = [];
+    }
+    function endOperation() {
+      var reScroll = false, updated;
+      if (selectionChanged) reScroll = !scrollCursorIntoView();
+      if (changes.length) updated = updateDisplay(changes, true);
+      else {
+        if (selectionChanged) updateSelection();
+        if (gutterDirty) updateGutter();
+      }
+      if (reScroll) scrollCursorIntoView();
+      if (selectionChanged) {scrollEditorIntoView(); restartBlink();}
+
+      if (focused && !leaveInputAlone &&
+          (updateInput === true || (updateInput !== false && selectionChanged)))
+        resetInput(userSelChange);
+
+      if (selectionChanged && options.matchBrackets)
+        setTimeout(operation(function() {
+          if (bracketHighlighted) {bracketHighlighted(); bracketHighlighted = null;}
+          if (posEq(sel.from, sel.to)) matchBrackets(false);
+        }), 20);
+      var tc = textChanged, cbs = callbacks; // these can be reset by callbacks
+      if (selectionChanged && options.onCursorActivity)
+        options.onCursorActivity(instance);
+      if (tc && options.onChange && instance)
+        options.onChange(instance, tc);
+      for (var i = 0; i < cbs.length; ++i) cbs[i](instance);
+      if (updated && options.onUpdate) options.onUpdate(instance);
+    }
+    var nestedOperation = 0;
+    function operation(f) {
+      return function() {
+        if (!nestedOperation++) startOperation();
+        try {var result = f.apply(this, arguments);}
+        finally {if (!--nestedOperation) endOperation();}
+        return result;
+      };
+    }
+
+    function compoundChange(f) {
+      history.startCompound();
+      try { return f(); } finally { history.endCompound(); }
+    }
+
+    for (var ext in extensions)
+      if (extensions.propertyIsEnumerable(ext) &&
+          !instance.propertyIsEnumerable(ext))
+        instance[ext] = extensions[ext];
+    return instance;
+  } // (end of function CodeMirror)
+
+  // The default configuration options.
+  CodeMirror.defaults = {
+    value: "",
+    mode: null,
+    theme: "default",
+    indentUnit: 2,
+    indentWithTabs: false,
+    smartIndent: true,
+    tabSize: 4,
+    keyMap: "default",
+    extraKeys: null,
+    electricChars: true,
+    autoClearEmptyLines: false,
+    onKeyEvent: null,
+    onDragEvent: null,
+    lineWrapping: false,
+    lineNumbers: false,
+    gutter: false,
+    fixedGutter: false,
+    firstLineNumber: 1,
+    readOnly: false,
+    dragDrop: true,
+    onChange: null,
+    onCursorActivity: null,
+    onGutterClick: null,
+    onHighlightComplete: null,
+    onUpdate: null,
+    onFocus: null, onBlur: null, onScroll: null,
+    matchBrackets: false,
+    workTime: 100,
+    workDelay: 200,
+    pollInterval: 100,
+    undoDepth: 40,
+    tabindex: null,
+    autofocus: null
+  };
+
+  var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent);
+  var mac = ios || /Mac/.test(navigator.platform);
+  var win = /Win/.test(navigator.platform);
+
+  // Known modes, by name and by MIME
+  var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
+  CodeMirror.defineMode = function(name, mode) {
+    if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
+    if (arguments.length > 2) {
+      mode.dependencies = [];
+      for (var i = 2; i < arguments.length; ++i) mode.dependencies.push(arguments[i]);
+    }
+    modes[name] = mode;
+  };
+  CodeMirror.defineMIME = function(mime, spec) {
+    mimeModes[mime] = spec;
+  };
+  CodeMirror.resolveMode = function(spec) {
+    if (typeof spec == "string" && mimeModes.hasOwnProperty(spec))
+      spec = mimeModes[spec];
+    else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec))
+      return CodeMirror.resolveMode("application/xml");
+    if (typeof spec == "string") return {name: spec};
+    else return spec || {name: "null"};
+  };
+  CodeMirror.getMode = function(options, spec) {
+    var spec = CodeMirror.resolveMode(spec);
+    var mfactory = modes[spec.name];
+    if (!mfactory) return CodeMirror.getMode(options, "text/plain");
+    return mfactory(options, spec);
+  };
+  CodeMirror.listModes = function() {
+    var list = [];
+    for (var m in modes)
+      if (modes.propertyIsEnumerable(m)) list.push(m);
+    return list;
+  };
+  CodeMirror.listMIMEs = function() {
+    var list = [];
+    for (var m in mimeModes)
+      if (mimeModes.propertyIsEnumerable(m)) list.push({mime: m, mode: mimeModes[m]});
+    return list;
+  };
+
+  var extensions = CodeMirror.extensions = {};
+  CodeMirror.defineExtension = function(name, func) {
+    extensions[name] = func;
+  };
+
+  var commands = CodeMirror.commands = {
+    selectAll: function(cm) {cm.setSelection({line: 0, ch: 0}, {line: cm.lineCount() - 1});},
+    killLine: function(cm) {
+      var from = cm.getCursor(true), to = cm.getCursor(false), sel = !posEq(from, to);
+      if (!sel && cm.getLine(from.line).length == from.ch) cm.replaceRange("", from, {line: from.line + 1, ch: 0});
+      else cm.replaceRange("", from, sel ? to : {line: from.line});
+    },
+    deleteLine: function(cm) {var l = cm.getCursor().line; cm.replaceRange("", {line: l, ch: 0}, {line: l});},
+    undo: function(cm) {cm.undo();},
+    redo: function(cm) {cm.redo();},
+    goDocStart: function(cm) {cm.setCursor(0, 0, true);},
+    goDocEnd: function(cm) {cm.setSelection({line: cm.lineCount() - 1}, null, true);},
+    goLineStart: function(cm) {cm.setCursor(cm.getCursor().line, 0, true);},
+    goLineStartSmart: function(cm) {
+      var cur = cm.getCursor();
+      var text = cm.getLine(cur.line), firstNonWS = Math.max(0, text.search(/\S/));
+      cm.setCursor(cur.line, cur.ch <= firstNonWS && cur.ch ? 0 : firstNonWS, true);
+    },
+    goLineEnd: function(cm) {cm.setSelection({line: cm.getCursor().line}, null, true);},
+    goLineUp: function(cm) {cm.moveV(-1, "line");},
+    goLineDown: function(cm) {cm.moveV(1, "line");},
+    goPageUp: function(cm) {cm.moveV(-1, "page");},
+    goPageDown: function(cm) {cm.moveV(1, "page");},
+    goCharLeft: function(cm) {cm.moveH(-1, "char");},
+    goCharRight: function(cm) {cm.moveH(1, "char");},
+    goColumnLeft: function(cm) {cm.moveH(-1, "column");},
+    goColumnRight: function(cm) {cm.moveH(1, "column");},
+    goWordLeft: function(cm) {cm.moveH(-1, "word");},
+    goWordRight: function(cm) {cm.moveH(1, "word");},
+    delCharLeft: function(cm) {cm.deleteH(-1, "char");},
+    delCharRight: function(cm) {cm.deleteH(1, "char");},
+    delWordLeft: function(cm) {cm.deleteH(-1, "word");},
+    delWordRight: function(cm) {cm.deleteH(1, "word");},
+    indentAuto: function(cm) {cm.indentSelection("smart");},
+    indentMore: function(cm) {cm.indentSelection("add");},
+    indentLess: function(cm) {cm.indentSelection("subtract");},
+    insertTab: function(cm) {cm.replaceSelection("\t", "end");},
+    defaultTab: function(cm) {
+      if (cm.somethingSelected()) cm.indentSelection("add");
+      else cm.replaceSelection("\t", "end");
+    },
+    transposeChars: function(cm) {
+      var cur = cm.getCursor(), line = cm.getLine(cur.line);
+      if (cur.ch > 0 && cur.ch < line.length - 1)
+        cm.replaceRange(line.charAt(cur.ch) + line.charAt(cur.ch - 1),
+                        {line: cur.line, ch: cur.ch - 1}, {line: cur.line, ch: cur.ch + 1});
+    },
+    newlineAndIndent: function(cm) {
+      cm.replaceSelection("\n","\n");
+      cm.indentLine(cm.getCursor().line);
+    },
+    toggleOverwrite: function(cm) {cm.toggleOverwrite();}
+  };
+
+  var keyMap = CodeMirror.keyMap = {};
+  keyMap.basic = {
+    "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
+    "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
+    "Delete": "delCharRight", "Backspace": "delCharLeft", "Tab": "defaultTab", "Shift-Tab": "indentAuto",
+    "Enter": "newlineAndIndent", "Insert": "toggleOverwrite"
+  };
+  // Note that the save and find-related commands aren't defined by
+  // default. Unknown commands are simply ignored.
+  keyMap.pcDefault = {
+    "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
+    "Ctrl-Home": "goDocStart", "Alt-Up": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Down": "goDocEnd",
+    "Ctrl-Left": "goWordLeft", "Ctrl-Right": "goWordRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
+    "Ctrl-Backspace": "delWordLeft", "Ctrl-Delete": "delWordRight", "Ctrl-S": "save", "Ctrl-F": "find",
+    "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
+    "Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
+    fallthrough: "basic"
+  };
+  keyMap.macDefault = {
+    "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
+    "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goWordLeft",
+    "Alt-Right": "goWordRight", "Cmd-Left": "goLineStart", "Cmd-Right": "goLineEnd", "Alt-Backspace": "delWordLeft",
+    "Ctrl-Alt-Backspace": "delWordRight", "Alt-Delete": "delWordRight", "Cmd-S": "save", "Cmd-F": "find",
+    "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
+    "Cmd-[": "indentLess", "Cmd-]": "indentMore",
+    fallthrough: ["basic", "emacsy"]
+  };
+  keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
+  keyMap.emacsy = {
+    "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
+    "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
+    "Ctrl-V": "goPageUp", "Shift-Ctrl-V": "goPageDown", "Ctrl-D": "delCharRight", "Ctrl-H": "delCharLeft",
+    "Alt-D": "delWordRight", "Alt-Backspace": "delWordLeft", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars"
+  };
+
+  function getKeyMap(val) {
+    if (typeof val == "string") return keyMap[val];
+    else return val;
+  }
+  function lookupKey(name, extraMap, map, handle, stop) {
+    function lookup(map) {
+      map = getKeyMap(map);
+      var found = map[name];
+      if (found != null && handle(found)) return true;
+      if (map.nofallthrough) {
+        if (stop) stop();
+        return true;
+      }
+      var fallthrough = map.fallthrough;
+      if (fallthrough == null) return false;
+      if (Object.prototype.toString.call(fallthrough) != "[object Array]")
+        return lookup(fallthrough);
+      for (var i = 0, e = fallthrough.length; i < e; ++i) {
+        if (lookup(fallthrough[i])) return true;
+      }
+      return false;
+    }
+    if (extraMap && lookup(extraMap)) return true;
+    return lookup(map);
+  }
+  function isModifierKey(event) {
+    var name = keyNames[e_prop(event, "keyCode")];
+    return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod";
+  }
+
+  CodeMirror.fromTextArea = function(textarea, options) {
+    if (!options) options = {};
+    options.value = textarea.value;
+    if (!options.tabindex && textarea.tabindex)
+      options.tabindex = textarea.tabindex;
+    if (options.autofocus == null && textarea.getAttribute("autofocus") != null)
+      options.autofocus = true;
+
+    function save() {textarea.value = instance.getValue();}
+    if (textarea.form) {
+      // Deplorable hack to make the submit method do the right thing.
+      var rmSubmit = connect(textarea.form, "submit", save, true);
+      if (typeof textarea.form.submit == "function") {
+        var realSubmit = textarea.form.submit;
+        function wrappedSubmit() {
+          save();
+          textarea.form.submit = realSubmit;
+          textarea.form.submit();
+          textarea.form.submit = wrappedSubmit;
+        }
+        textarea.form.submit = wrappedSubmit;
+      }
+    }
+
+    textarea.style.display = "none";
+    var instance = CodeMirror(function(node) {
+      textarea.parentNode.insertBefore(node, textarea.nextSibling);
+    }, options);
+    instance.save = save;
+    instance.getTextArea = function() { return textarea; };
+    instance.toTextArea = function() {
+      save();
+      textarea.parentNode.removeChild(instance.getWrapperElement());
+      textarea.style.display = "";
+      if (textarea.form) {
+        rmSubmit();
+        if (typeof textarea.form.submit == "function")
+          textarea.form.submit = realSubmit;
+      }
+    };
+    return instance;
+  };
+
+  // Utility functions for working with state. Exported because modes
+  // sometimes need to do this.
+  function copyState(mode, state) {
+    if (state === true) return state;
+    if (mode.copyState) return mode.copyState(state);
+    var nstate = {};
+    for (var n in state) {
+      var val = state[n];
+      if (val instanceof Array) val = val.concat([]);
+      nstate[n] = val;
+    }
+    return nstate;
+  }
+  CodeMirror.copyState = copyState;
+  function startState(mode, a1, a2) {
+    return mode.startState ? mode.startState(a1, a2) : true;
+  }
+  CodeMirror.startState = startState;
+
+  // The character stream used by a mode's parser.
+  function StringStream(string, tabSize) {
+    this.pos = this.start = 0;
+    this.string = string;
+    this.tabSize = tabSize || 8;
+  }
+  StringStream.prototype = {
+    eol: function() {return this.pos >= this.string.length;},
+    sol: function() {return this.pos == 0;},
+    peek: function() {return this.string.charAt(this.pos);},
+    next: function() {
+      if (this.pos < this.string.length)
+        return this.string.charAt(this.pos++);
+    },
+    eat: function(match) {
+      var ch = this.string.charAt(this.pos);
+      if (typeof match == "string") var ok = ch == match;
+      else var ok = ch && (match.test ? match.test(ch) : match(ch));
+      if (ok) {++this.pos; return ch;}
+    },
+    eatWhile: function(match) {
+      var start = this.pos;
+      while (this.eat(match)){}
+      return this.pos > start;
+    },
+    eatSpace: function() {
+      var start = this.pos;
+      while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
+      return this.pos > start;
+    },
+    skipToEnd: function() {this.pos = this.string.length;},
+    skipTo: function(ch) {
+      var found = this.string.indexOf(ch, this.pos);
+      if (found > -1) {this.pos = found; return true;}
+    },
+    backUp: function(n) {this.pos -= n;},
+    column: function() {return countColumn(this.string, this.start, this.tabSize);},
+    indentation: function() {return countColumn(this.string, null, this.tabSize);},
+    match: function(pattern, consume, caseInsensitive) {
+      if (typeof pattern == "string") {
+        function cased(str) {return caseInsensitive ? str.toLowerCase() : str;}
+        if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) {
+          if (consume !== false) this.pos += pattern.length;
+          return true;
+        }
+      }
+      else {
+        var match = this.string.slice(this.pos).match(pattern);
+        if (match && consume !== false) this.pos += match[0].length;
+        return match;
+      }
+    },
+    current: function(){return this.string.slice(this.start, this.pos);}
+  };
+  CodeMirror.StringStream = StringStream;
+
+  function MarkedText(from, to, className, marker) {
+    this.from = from; this.to = to; this.style = className; this.marker = marker;
+  }
+  MarkedText.prototype = {
+    attach: function(line) { this.marker.set.push(line); },
+    detach: function(line) {
+      var ix = indexOf(this.marker.set, line);
+      if (ix > -1) this.marker.set.splice(ix, 1);
+    },
+    split: function(pos, lenBefore) {
+      if (this.to <= pos && this.to != null) return null;
+      var from = this.from < pos || this.from == null ? null : this.from - pos + lenBefore;
+      var to = this.to == null ? null : this.to - pos + lenBefore;
+      return new MarkedText(from, to, this.style, this.marker);
+    },
+    dup: function() { return new MarkedText(null, null, this.style, this.marker); },
+    clipTo: function(fromOpen, from, toOpen, to, diff) {
+      if (fromOpen && to > this.from && (to < this.to || this.to == null))
+        this.from = null;
+      else if (this.from != null && this.from >= from)
+        this.from = Math.max(to, this.from) + diff;
+      if (toOpen && (from < this.to || this.to == null) && (from > this.from || this.from == null))
+        this.to = null;
+      else if (this.to != null && this.to > from)
+        this.to = to < this.to ? this.to + diff : from;
+    },
+    isDead: function() { return this.from != null && this.to != null && this.from >= this.to; },
+    sameSet: function(x) { return this.marker == x.marker; }
+  };
+
+  function Bookmark(pos) {
+    this.from = pos; this.to = pos; this.line = null;
+  }
+  Bookmark.prototype = {
+    attach: function(line) { this.line = line; },
+    detach: function(line) { if (this.line == line) this.line = null; },
+    split: function(pos, lenBefore) {
+      if (pos < this.from) {
+        this.from = this.to = (this.from - pos) + lenBefore;
+        return this;
+      }
+    },
+    isDead: function() { return this.from > this.to; },
+    clipTo: function(fromOpen, from, toOpen, to, diff) {
+      if ((fromOpen || from < this.from) && (toOpen || to > this.to)) {
+        this.from = 0; this.to = -1;
+      } else if (this.from > from) {
+        this.from = this.to = Math.max(to, this.from) + diff;
+      }
+    },
+    sameSet: function(x) { return false; },
+    find: function() {
+      if (!this.line || !this.line.parent) return null;
+      return {line: lineNo(this.line), ch: this.from};
+    },
+    clear: function() {
+      if (this.line) {
+        var found = indexOf(this.line.marked, this);
+        if (found != -1) this.line.marked.splice(found, 1);
+        this.line = null;
+      }
+    }
+  };
+
+  // Line objects. These hold state related to a line, including
+  // highlighting info (the styles array).
+  function Line(text, styles) {
+    this.styles = styles || [text, null];
+    this.text = text;
+    this.height = 1;
+    this.marked = this.gutterMarker = this.className = this.bgClassName = this.handlers = null;
+    this.stateAfter = this.parent = this.hidden = null;
+  }
+  Line.inheritMarks = function(text, orig) {
+    var ln = new Line(text), mk = orig && orig.marked;
+    if (mk) {
+      for (var i = 0; i < mk.length; ++i) {
+        if (mk[i].to == null && mk[i].style) {
+          var newmk = ln.marked || (ln.marked = []), mark = mk[i];
+          var nmark = mark.dup(); newmk.push(nmark); nmark.attach(ln);
+        }
+      }
+    }
+    return ln;
+  }
+  Line.prototype = {
+    // Replace a piece of a line, keeping the styles around it intact.
+    replace: function(from, to_, text) {
+      var st = [], mk = this.marked, to = to_ == null ? this.text.length : to_;
+      copyStyles(0, from, this.styles, st);
+      if (text) st.push(text, null);
+      copyStyles(to, this.text.length, this.styles, st);
+      this.styles = st;
+      this.text = this.text.slice(0, from) + text + this.text.slice(to);
+      this.stateAfter = null;
+      if (mk) {
+        var diff = text.length - (to - from);
+        for (var i = 0; i < mk.length; ++i) {
+          var mark = mk[i];
+          mark.clipTo(from == null, from || 0, to_ == null, to, diff);
+          if (mark.isDead()) {mark.detach(this); mk.splice(i--, 1);}
+        }
+      }
+    },
+    // Split a part off a line, keeping styles and markers intact.
+    split: function(pos, textBefore) {
+      var st = [textBefore, null], mk = this.marked;
+      copyStyles(pos, this.text.length, this.styles, st);
+      var taken = new Line(textBefore + this.text.slice(pos), st);
+      if (mk) {
+        for (var i = 0; i < mk.length; ++i) {
+          var mark = mk[i];
+          var newmark = mark.split(pos, textBefore.length);
+          if (newmark) {
+            if (!taken.marked) taken.marked = [];
+            taken.marked.push(newmark); newmark.attach(taken);
+            if (newmark == mark) mk.splice(i--, 1);
+          }
+        }
+      }
+      return taken;
+    },
+    append: function(line) {
+      var mylen = this.text.length, mk = line.marked, mymk = this.marked;
+      this.text += line.text;
+      copyStyles(0, line.text.length, line.styles, this.styles);
+      if (mymk) {
+        for (var i = 0; i < mymk.length; ++i)
+          if (mymk[i].to == null) mymk[i].to = mylen;
+      }
+      if (mk && mk.length) {
+        if (!mymk) this.marked = mymk = [];
+        outer: for (var i = 0; i < mk.length; ++i) {
+          var mark = mk[i];
+          if (!mark.from) {
+            for (var j = 0; j < mymk.length; ++j) {
+              var mymark = mymk[j];
+              if (mymark.to == mylen && mymark.sameSet(mark)) {
+                mymark.to = mark.to == null ? null : mark.to + mylen;
+                if (mymark.isDead()) {
+                  mymark.detach(this);
+                  mk.splice(i--, 1);
+                }
+                continue outer;
+              }
+            }
+          }
+          mymk.push(mark);
+          mark.attach(this);
+          mark.from += mylen;
+          if (mark.to != null) mark.to += mylen;
+        }
+      }
+    },
+    fixMarkEnds: function(other) {
+      var mk = this.marked, omk = other.marked;
+      if (!mk) return;
+      for (var i = 0; i < mk.length; ++i) {
+        var mark = mk[i], close = mark.to == null;
+        if (close && omk) {
+          for (var j = 0; j < omk.length; ++j)
+            if (omk[j].sameSet(mark)) {close = false; break;}
+        }
+        if (close) mark.to = this.text.length;
+      }
+    },
+    fixMarkStarts: function() {
+      var mk = this.marked;
+      if (!mk) return;
+      for (var i = 0; i < mk.length; ++i)
+        if (mk[i].from == null) mk[i].from = 0;
+    },
+    addMark: function(mark) {
+      mark.attach(this);
+      if (this.marked == null) this.marked = [];
+      this.marked.push(mark);
+      this.marked.sort(function(a, b){return (a.from || 0) - (b.from || 0);});
+    },
+    // Run the given mode's parser over a line, update the styles
+    // array, which contains alternating fragments of text and CSS
+    // classes.
+    highlight: function(mode, state, tabSize) {
+      var stream = new StringStream(this.text, tabSize), st = this.styles, pos = 0;
+      var changed = false, curWord = st[0], prevWord;
+      if (this.text == "" && mode.blankLine) mode.blankLine(state);
+      while (!stream.eol()) {
+        var style = mode.token(stream, state);
+        var substr = this.text.slice(stream.start, stream.pos);
+        stream.start = stream.pos;
+        if (pos && st[pos-1] == style)
+          st[pos-2] += substr;
+        else if (substr) {
+          if (!changed && (st[pos+1] != style || (pos && st[pos-2] != prevWord))) changed = true;
+          st[pos++] = substr; st[pos++] = style;
+          prevWord = curWord; curWord = st[pos];
+        }
+        // Give up when line is ridiculously long
+        if (stream.pos > 5000) {
+          st[pos++] = this.text.slice(stream.pos); st[pos++] = null;
+          break;
+        }
+      }
+      if (st.length != pos) {st.length = pos; changed = true;}
+      if (pos && st[pos-2] != prevWord) changed = true;
+      // Short lines with simple highlights return null, and are
+      // counted as changed by the driver because they are likely to
+      // highlight the same way in various contexts.
+      return changed || (st.length < 5 && this.text.length < 10 ? null : false);
+    },
+    // Fetch the parser token for a given character. Useful for hacks
+    // that want to inspect the mode state (say, for completion).
+    getTokenAt: function(mode, state, ch) {
+      var txt = this.text, stream = new StringStream(txt);
+      while (stream.pos < ch && !stream.eol()) {
+        stream.start = stream.pos;
+        var style = mode.token(stream, state);
+      }
+      return {start: stream.start,
+              end: stream.pos,
+              string: stream.current(),
+              className: style || null,
+              state: state};
+    },
+    indentation: function(tabSize) {return countColumn(this.text, null, tabSize);},
+    // Produces an HTML fragment for the line, taking selection,
+    // marking, and highlighting into account.
+    getHTML: function(makeTab, wrapAt, wrapId, wrapWBR) {
+      var html = [], first = true, col = 0;
+      function span_(text, style) {
+        if (!text) return;
+        // Work around a bug where, in some compat modes, IE ignores leading spaces
+        if (first && ie && text.charAt(0) == " ") text = "\u00a0" + text.slice(1);
+        first = false;
+        if (text.indexOf("\t") == -1) {
+          col += text.length;
+          var escaped = htmlEscape(text);
+        } else {
+          var escaped = "";
+          for (var pos = 0;;) {
+            var idx = text.indexOf("\t", pos);
+            if (idx == -1) {
+              escaped += htmlEscape(text.slice(pos));
+              col += text.length - pos;
+              break;
+            } else {
+              col += idx - pos;
+              var tab = makeTab(col);
+              escaped += htmlEscape(text.slice(pos, idx)) + tab.html;
+              col += tab.width;
+              pos = idx + 1;
+            }
+          }
+        }
+        if (style) html.push('<span class="', style, '">', escaped, "</span>");
+        else html.push(escaped);
+      }
+      var span = span_;
+      if (wrapAt != null) {
+        var outPos = 0, open = "<span id=\"" + wrapId + "\">";
+        span = function(text, style) {
+          var l = text.length;
+          if (wrapAt >= outPos && wrapAt < outPos + l) {
+            if (wrapAt > outPos) {
+              span_(text.slice(0, wrapAt - outPos), style);
+              // See comment at the definition of spanAffectsWrapping
+              if (wrapWBR) html.push("<wbr>");
+            }
+            html.push(open);
+            var cut = wrapAt - outPos;
+            span_(window.opera ? text.slice(cut, cut + 1) : text.slice(cut), style);
+            html.push("</span>");
+            if (window.opera) span_(text.slice(cut + 1), style);
+            wrapAt--;
+            outPos += l;
+          } else {
+            outPos += l;
+            span_(text, style);
+            // Output empty wrapper when at end of line
+            if (outPos == wrapAt && outPos == len) html.push(open + " </span>");
+            // Stop outputting HTML when gone sufficiently far beyond measure
+            else if (outPos > wrapAt + 10 && /\s/.test(text)) span = function(){};
+          }
+        }
+      }
+
+      var st = this.styles, allText = this.text, marked = this.marked;
+      var len = allText.length;
+      function styleToClass(style) {
+        if (!style) return null;
+        return "cm-" + style.replace(/ +/g, " cm-");
+      }
+
+      if (!allText && wrapAt == null) {
+        span(" ");
+      } else if (!marked || !marked.length) {
+        for (var i = 0, ch = 0; ch < len; i+=2) {
+          var str = st[i], style = st[i+1], l = str.length;
+          if (ch + l > len) str = str.slice(0, len - ch);
+          ch += l;
+          span(str, styleToClass(style));
+        }
+      } else {
+        var pos = 0, i = 0, text = "", style, sg = 0;
+        var nextChange = marked[0].from || 0, marks = [], markpos = 0;
+        function advanceMarks() {
+          var m;
+          while (markpos < marked.length &&
+                 ((m = marked[markpos]).from == pos || m.from == null)) {
+            if (m.style != null) marks.push(m);
+            ++markpos;
+          }
+          nextChange = markpos < marked.length ? marked[markpos].from : Infinity;
+          for (var i = 0; i < marks.length; ++i) {
+            var to = marks[i].to || Infinity;
+            if (to == pos) marks.splice(i--, 1);
+            else nextChange = Math.min(to, nextChange);
+          }
+        }
+        var m = 0;
+        while (pos < len) {
+          if (nextChange == pos) advanceMarks();
+          var upto = Math.min(len, nextChange);
+          while (true) {
+            if (text) {
+              var end = pos + text.length;
+              var appliedStyle = style;
+              for (var j = 0; j < marks.length; ++j)
+                appliedStyle = (appliedStyle ? appliedStyle + " " : "") + marks[j].style;
+              span(end > upto ? text.slice(0, upto - pos) : text, appliedStyle);
+              if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
+              pos = end;
+            }
+            text = st[i++]; style = styleToClass(st[i++]);
+          }
+        }
+      }
+      return html.join("");
+    },
+    cleanUp: function() {
+      this.parent = null;
+      if (this.marked)
+        for (var i = 0, e = this.marked.length; i < e; ++i) this.marked[i].detach(this);
+    }
+  };
+  // Utility used by replace and split above
+  function copyStyles(from, to, source, dest) {
+    for (var i = 0, pos = 0, state = 0; pos < to; i+=2) {
+      var part = source[i], end = pos + part.length;
+      if (state == 0) {
+        if (end > from) dest.push(part.slice(from - pos, Math.min(part.length, to - pos)), source[i+1]);
+        if (end >= from) state = 1;
+      }
+      else if (state == 1) {
+        if (end > to) dest.push(part.slice(0, to - pos), source[i+1]);
+        else dest.push(part, source[i+1]);
+      }
+      pos = end;
+    }
+  }
+
+  // Data structure that holds the sequence of lines.
+  function LeafChunk(lines) {
+    this.lines = lines;
+    this.parent = null;
+    for (var i = 0, e = lines.length, height = 0; i < e; ++i) {
+      lines[i].parent = this;
+      height += lines[i].height;
+    }
+    this.height = height;
+  }
+  LeafChunk.prototype = {
+    chunkSize: function() { return this.lines.length; },
+    remove: function(at, n, callbacks) {
+      for (var i = at, e = at + n; i < e; ++i) {
+        var line = this.lines[i];
+        this.height -= line.height;
+        line.cleanUp();
+        if (line.handlers)
+          for (var j = 0; j < line.handlers.length; ++j) callbacks.push(line.handlers[j]);
+      }
+      this.lines.splice(at, n);
+    },
+    collapse: function(lines) {
+      lines.splice.apply(lines, [lines.length, 0].concat(this.lines));
+    },
+    insertHeight: function(at, lines, height) {
+      this.height += height;
+      // The trick below is apparently too advanced for IE, which
+      // occasionally corrupts this.lines (duplicating elements) when
+      // it is used.
+      if (ie) this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at));
+      else this.lines.splice.apply(this.lines, [at, 0].concat(lines));
+      for (var i = 0, e = lines.length; i < e; ++i) lines[i].parent = this;
+    },
+    iterN: function(at, n, op) {
+      for (var e = at + n; at < e; ++at)
+        if (op(this.lines[at])) return true;
+    }
+  };
+  function BranchChunk(children) {
+    this.children = children;
+    var size = 0, height = 0;
+    for (var i = 0, e = children.length; i < e; ++i) {
+      var ch = children[i];
+      size += ch.chunkSize(); height += ch.height;
+      ch.parent = this;
+    }
+    this.size = size;
+    this.height = height;
+    this.parent = null;
+  }
+  BranchChunk.prototype = {
+    chunkSize: function() { return this.size; },
+    remove: function(at, n, callbacks) {
+      this.size -= n;
+      for (var i = 0; i < this.children.length; ++i) {
+        var child = this.children[i], sz = child.chunkSize();
+        if (at < sz) {
+          var rm = Math.min(n, sz - at), oldHeight = child.height;
+          child.remove(at, rm, callbacks);
+          this.height -= oldHeight - child.height;
+          if (sz == rm) { this.children.splice(i--, 1); child.parent = null; }
+          if ((n -= rm) == 0) break;
+          at = 0;
+        } else at -= sz;
+      }
+      if (this.size - n < 25) {
+        var lines = [];
+        this.collapse(lines);
+        this.children = [new LeafChunk(lines)];
+        this.children[0].parent = this;
+      }
+    },
+    collapse: function(lines) {
+      for (var i = 0, e = this.children.length; i < e; ++i) this.children[i].collapse(lines);
+    },
+    insert: function(at, lines) {
+      var height = 0;
+      for (var i = 0, e = lines.length; i < e; ++i) height += lines[i].height;
+      this.insertHeight(at, lines, height);
+    },
+    insertHeight: function(at, lines, height) {
+      this.size += lines.length;
+      this.height += height;
+      for (var i = 0, e = this.children.length; i < e; ++i) {
+        var child = this.children[i], sz = child.chunkSize();
+        if (at <= sz) {
+          child.insertHeight(at, lines, height);
+          if (child.lines && child.lines.length > 50) {
+            while (child.lines.length > 50) {
+              var spilled = child.lines.splice(child.lines.length - 25, 25);
+              var newleaf = new LeafChunk(spilled);
+              child.height -= newleaf.height;
+              this.children.splice(i + 1, 0, newleaf);
+              newleaf.parent = this;
+            }
+            this.maybeSpill();
+          }
+          break;
+        }
+        at -= sz;
+      }
+    },
+    maybeSpill: function() {
+      if (this.children.length <= 10) return;
+      var me = this;
+      do {
+        var spilled = me.children.splice(me.children.length - 5, 5);
+        var sibling = new BranchChunk(spilled);
+        if (!me.parent) { // Become the parent node
+          var copy = new BranchChunk(me.children);
+          copy.parent = me;
+          me.children = [copy, sibling];
+          me = copy;
+        } else {
+          me.size -= sibling.size;
+          me.height -= sibling.height;
+          var myIndex = indexOf(me.parent.children, me);
+          me.parent.children.splice(myIndex + 1, 0, sibling);
+        }
+        sibling.parent = me.parent;
+      } while (me.children.length > 10);
+      me.parent.maybeSpill();
+    },
+    iter: function(from, to, op) { this.iterN(from, to - from, op); },
+    iterN: function(at, n, op) {
+      for (var i = 0, e = this.children.length; i < e; ++i) {
+        var child = this.children[i], sz = child.chunkSize();
+        if (at < sz) {
+          var used = Math.min(n, sz - at);
+          if (child.iterN(at, used, op)) return true;
+          if ((n -= used) == 0) break;
+          at = 0;
+        } else at -= sz;
+      }
+    }
+  };
+
+  function getLineAt(chunk, n) {
+    while (!chunk.lines) {
+      for (var i = 0;; ++i) {
+        var child = chunk.children[i], sz = child.chunkSize();
+        if (n < sz) { chunk = child; break; }
+        n -= sz;
+      }
+    }
+    return chunk.lines[n];
+  }
+  function lineNo(line) {
+    if (line.parent == null) return null;
+    var cur = line.parent, no = indexOf(cur.lines, line);
+    for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {
+      for (var i = 0, e = chunk.children.length; ; ++i) {
+        if (chunk.children[i] == cur) break;
+        no += chunk.children[i].chunkSize();
+      }
+    }
+    return no;
+  }
+  function lineAtHeight(chunk, h) {
+    var n = 0;
+    outer: do {
+      for (var i = 0, e = chunk.children.length; i < e; ++i) {
+        var child = chunk.children[i], ch = child.height;
+        if (h < ch) { chunk = child; continue outer; }
+        h -= ch;
+        n += child.chunkSize();
+      }
+      return n;
+    } while (!chunk.lines);
+    for (var i = 0, e = chunk.lines.length; i < e; ++i) {
+      var line = chunk.lines[i], lh = line.height;
+      if (h < lh) break;
+      h -= lh;
+    }
+    return n + i;
+  }
+  function heightAtLine(chunk, n) {
+    var h = 0;
+    outer: do {
+      for (var i = 0, e = chunk.children.length; i < e; ++i) {
+        var child = chunk.children[i], sz = child.chunkSize();
+        if (n < sz) { chunk = child; continue outer; }
+        n -= sz;
+        h += child.height;
+      }
+      return h;
+    } while (!chunk.lines);
+    for (var i = 0; i < n; ++i) h += chunk.lines[i].height;
+    return h;
+  }
+
+  // The history object 'chunks' changes that are made close together
+  // and at almost the same time into bigger undoable units.
+  function History() {
+    this.time = 0;
+    this.done = []; this.undone = [];
+    this.compound = 0;
+    this.closed = false;
+  }
+  History.prototype = {
+    addChange: function(start, added, old) {
+      this.undone.length = 0;
+      var time = +new Date, cur = this.done[this.done.length - 1], last = cur && cur[cur.length - 1];
+      var dtime = time - this.time;
+
+      if (this.compound && cur && !this.closed) {
+        cur.push({start: start, added: added, old: old});
+      } else if (dtime > 400 || !last || this.closed ||
+                 last.start > start + old.length || last.start + last.added < start) {
+        this.done.push([{start: start, added: added, old: old}]);
+        this.closed = false;
+      } else {
+        var startBefore = Math.max(0, last.start - start),
+            endAfter = Math.max(0, (start + old.length) - (last.start + last.added));
+        for (var i = startBefore; i > 0; --i) last.old.unshift(old[i - 1]);
+        for (var i = endAfter; i > 0; --i) last.old.push(old[old.length - i]);
+        if (startBefore) last.start = start;
+        last.added += added - (old.length - startBefore - endAfter);
+      }
+      this.time = time;
+    },
+    startCompound: function() {
+      if (!this.compound++) this.closed = true;
+    },
+    endCompound: function() {
+      if (!--this.compound) this.closed = true;
+    }
+  };
+
+  function stopMethod() {e_stop(this);}
+  // Ensure an event has a stop method.
+  function addStop(event) {
+    if (!event.stop) event.stop = stopMethod;
+    return event;
+  }
+
+  function e_preventDefault(e) {
+    if (e.preventDefault) e.preventDefault();
+    else e.returnValue = false;
+  }
+  function e_stopPropagation(e) {
+    if (e.stopPropagation) e.stopPropagation();
+    else e.cancelBubble = true;
+  }
+  function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);}
+  CodeMirror.e_stop = e_stop;
+  CodeMirror.e_preventDefault = e_preventDefault;
+  CodeMirror.e_stopPropagation = e_stopPropagation;
+
+  function e_target(e) {return e.target || e.srcElement;}
+  function e_button(e) {
+    if (e.which) return e.which;
+    else if (e.button & 1) return 1;
+    else if (e.button & 2) return 3;
+    else if (e.button & 4) return 2;
+  }
+
+  // Allow 3rd-party code to override event properties by adding an override
+  // object to an event object.
+  function e_prop(e, prop) {
+    var overridden = e.override && e.override.hasOwnProperty(prop);
+    return overridden ? e.override[prop] : e[prop];
+  }
+
+  // Event handler registration. If disconnect is true, it'll return a
+  // function that unregisters the handler.
+  function connect(node, type, handler, disconnect) {
+    if (typeof node.addEventListener == "function") {
+      node.addEventListener(type, handler, false);
+      if (disconnect) return function() {node.removeEventListener(type, handler, false);};
+    }
+    else {
+      var wrapHandler = function(event) {handler(event || window.event);};
+      node.attachEvent("on" + type, wrapHandler);
+      if (disconnect) return function() {node.detachEvent("on" + type, wrapHandler);};
+    }
+  }
+  CodeMirror.connect = connect;
+
+  function Delayed() {this.id = null;}
+  Delayed.prototype = {set: function(ms, f) {clearTimeout(this.id); this.id = setTimeout(f, ms);}};
+
+  var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}};
+
+  var gecko = /gecko\/\d{7}/i.test(navigator.userAgent);
+  var ie = /MSIE \d/.test(navigator.userAgent);
+  var ie_lt9 = /MSIE [1-8]\b/.test(navigator.userAgent);
+  var quirksMode = ie && document.documentMode == 5;
+  var webkit = /WebKit\//.test(navigator.userAgent);
+  var chrome = /Chrome\//.test(navigator.userAgent);
+  var safari = /Apple Computer/.test(navigator.vendor);
+  var khtml = /KHTML\//.test(navigator.userAgent);
+
+  // Detect drag-and-drop
+  var dragAndDrop = function() {
+    // There is *some* kind of drag-and-drop support in IE6-8, but I
+    // couldn't get it to work yet.
+    if (ie_lt9) return false;
+    var div = document.createElement('div');
+    return "draggable" in div || "dragDrop" in div;
+  }();
+
+  // Feature-detect whether newlines in textareas are converted to \r\n
+  var lineSep = function () {
+    var te = document.createElement("textarea");
+    te.value = "foo\nbar";
+    if (te.value.indexOf("\r") > -1) return "\r\n";
+    return "\n";
+  }();
+
+  // For a reason I have yet to figure out, some browsers disallow
+  // word wrapping between certain characters *only* if a new inline
+  // element is started between them. This makes it hard to reliably
+  // measure the position of things, since that requires inserting an
+  // extra span. This terribly fragile set of regexps matches the
+  // character combinations that suffer from this phenomenon on the
+  // various browsers.
+  var spanAffectsWrapping = /^$/; // Won't match any two-character string
+  if (gecko) spanAffectsWrapping = /$'/;
+  else if (safari) spanAffectsWrapping = /\-[^ \-?]|\?[^ !'\"\),.\-\/:;\?\]\}]/;
+  else if (chrome) spanAffectsWrapping = /\-[^ \-\.?]|\?[^ \-\.?\]\}:;!'\"\),\/]|[\.!\"#&%\)*+,:;=>\]|\}~][\(\{\[<]|\$'/;
+
+  // Counts the column offset in a string, taking tabs into account.
+  // Used mostly to find indentation.
+  function countColumn(string, end, tabSize) {
+    if (end == null) {
+      end = string.search(/[^\s\u00a0]/);
+      if (end == -1) end = string.length;
+    }
+    for (var i = 0, n = 0; i < end; ++i) {
+      if (string.charAt(i) == "\t") n += tabSize - (n % tabSize);
+      else ++n;
+    }
+    return n;
+  }
+
+  function computedStyle(elt) {
+    if (elt.currentStyle) return elt.currentStyle;
+    return window.getComputedStyle(elt, null);
+  }
+
+  // Find the position of an element by following the offsetParent chain.
+  // If screen==true, it returns screen (rather than page) coordinates.
+  function eltOffset(node, screen) {
+    var bod = node.ownerDocument.body;
+    var x = 0, y = 0, skipBody = false;
+    for (var n = node; n; n = n.offsetParent) {
+      var ol = n.offsetLeft, ot = n.offsetTop;
+      // Firefox reports weird inverted offsets when the body has a border.
+      if (n == bod) { x += Math.abs(ol); y += Math.abs(ot); }
+      else { x += ol, y += ot; }
+      if (screen && computedStyle(n).position == "fixed")
+        skipBody = true;
+    }
+    var e = screen && !skipBody ? null : bod;
+    for (var n = node.parentNode; n != e; n = n.parentNode)
+      if (n.scrollLeft != null) { x -= n.scrollLeft; y -= n.scrollTop;}
+    return {left: x, top: y};
+  }
+  // Use the faster and saner getBoundingClientRect method when possible.
+  if (document.documentElement.getBoundingClientRect != null) eltOffset = function(node, screen) {
+    // Take the parts of bounding client rect that we are interested in so we are able to edit if need be,
+    // since the returned value cannot be changed externally (they are kept in sync as the element moves within the page)
+    try { var box = node.getBoundingClientRect(); box = { top: box.top, left: box.left }; }
+    catch(e) { box = {top: 0, left: 0}; }
+    if (!screen) {
+      // Get the toplevel scroll, working around browser differences.
+      if (window.pageYOffset == null) {
+        var t = document.documentElement || document.body.parentNode;
+        if (t.scrollTop == null) t = document.body;
+        box.top += t.scrollTop; box.left += t.scrollLeft;
+      } else {
+        box.top += window.pageYOffset; box.left += window.pageXOffset;
+      }
+    }
+    return box;
+  };
+
+  // Get a node's text content.
+  function eltText(node) {
+    return node.textContent || node.innerText || node.nodeValue || "";
+  }
+  function selectInput(node) {
+    if (ios) { // Mobile Safari apparently has a bug where select() is broken.
+      node.selectionStart = 0;
+      node.selectionEnd = node.value.length;
+    } else node.select();
+  }
+
+  // Operations on {line, ch} objects.
+  function posEq(a, b) {return a.line == b.line && a.ch == b.ch;}
+  function posLess(a, b) {return a.line < b.line || (a.line == b.line && a.ch < b.ch);}
+  function copyPos(x) {return {line: x.line, ch: x.ch};}
+
+  var escapeElement = document.createElement("pre");
+  function htmlEscape(str) {
+    escapeElement.textContent = str;
+    return escapeElement.innerHTML;
+  }
+  // Recent (late 2011) Opera betas insert bogus newlines at the start
+  // of the textContent, so we strip those.
+  if (htmlEscape("a") == "\na")
+    htmlEscape = function(str) {
+      escapeElement.textContent = str;
+      return escapeElement.innerHTML.slice(1);
+    };
+  // Some IEs don't preserve tabs through innerHTML
+  else if (htmlEscape("\t") != "\t")
+    htmlEscape = function(str) {
+      escapeElement.innerHTML = "";
+      escapeElement.appendChild(document.createTextNode(str));
+      return escapeElement.innerHTML;
+    };
+  CodeMirror.htmlEscape = htmlEscape;
+
+  // Used to position the cursor after an undo/redo by finding the
+  // last edited character.
+  function editEnd(from, to) {
+    if (!to) return 0;
+    if (!from) return to.length;
+    for (var i = from.length, j = to.length; i >= 0 && j >= 0; --i, --j)
+      if (from.charAt(i) != to.charAt(j)) break;
+    return j + 1;
+  }
+
+  function indexOf(collection, elt) {
+    if (collection.indexOf) return collection.indexOf(elt);
+    for (var i = 0, e = collection.length; i < e; ++i)
+      if (collection[i] == elt) return i;
+    return -1;
+  }
+  function isWordChar(ch) {
+    return /\w/.test(ch) || ch.toUpperCase() != ch.toLowerCase();
+  }
+
+  // See if "".split is the broken IE version, if so, provide an
+  // alternative way to split lines.
+  var splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) {
+    var pos = 0, nl, result = [];
+    while ((nl = string.indexOf("\n", pos)) > -1) {
+      result.push(string.slice(pos, string.charAt(nl-1) == "\r" ? nl - 1 : nl));
+      pos = nl + 1;
+    }
+    result.push(string.slice(pos));
+    return result;
+  } : function(string){return string.split(/\r?\n/);};
+  CodeMirror.splitLines = splitLines;
+
+  var hasSelection = window.getSelection ? function(te) {
+    try { return te.selectionStart != te.selectionEnd; }
+    catch(e) { return false; }
+  } : function(te) {
+    try {var range = te.ownerDocument.selection.createRange();}
+    catch(e) {}
+    if (!range || range.parentElement() != te) return false;
+    return range.compareEndPoints("StartToEnd", range) != 0;
+  };
+
+  CodeMirror.defineMode("null", function() {
+    return {token: function(stream) {stream.skipToEnd();}};
+  });
+  CodeMirror.defineMIME("text/plain", "null");
+
+  var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab",  16: "Shift", 17: "Ctrl", 18: "Alt",
+                  19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
+                  36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
+                  46: "Delete", 59: ";", 91: "Mod", 92: "Mod", 93: "Mod", 127: "Delete", 186: ";", 187: "=", 188: ",",
+                  189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", 221: "]", 222: "'", 63276: "PageUp",
+                  63277: "PageDown", 63275: "End", 63273: "Home", 63234: "Left", 63232: "Up", 63235: "Right",
+                  63233: "Down", 63302: "Insert", 63272: "Delete"};
+  CodeMirror.keyNames = keyNames;
+  (function() {
+    // Number keys
+    for (var i = 0; i < 10; i++) keyNames[i + 48] = String(i);
+    // Alphabetic keys
+    for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i);
+    // Function keys
+    for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i;
+  })();
+
+  return CodeMirror;
+})();
+
diff --git a/TestON/TAI/src/EditorScripts/dialog.js b/TestON/TAI/src/EditorScripts/dialog.js
new file mode 100644
index 0000000..95ba263
--- /dev/null
+++ b/TestON/TAI/src/EditorScripts/dialog.js
@@ -0,0 +1,63 @@
+// Open simple dialogs on top of an editor. Relies on dialog.css.
+
+(function() {
+  function dialogDiv(cm, template) {
+    var wrap = cm.getWrapperElement();
+    var dialog = wrap.insertBefore(document.createElement("div"), wrap.firstChild);
+    dialog.className = "CodeMirror-dialog";
+    dialog.innerHTML = '<div>' + template + '</div>';
+    return dialog;
+  }
+
+  CodeMirror.defineExtension("openDialog", function(template, callback) {
+    var dialog = dialogDiv(this, template);
+    var closed = false, me = this;
+    function close() {
+      if (closed) return;
+      closed = true;
+      dialog.parentNode.removeChild(dialog);
+    }
+    var inp = dialog.getElementsByTagName("input")[0];
+    if (inp) {
+      CodeMirror.connect(inp, "keydown", function(e) {
+        if (e.keyCode == 13 || e.keyCode == 27) {
+          CodeMirror.e_stop(e);
+          close();
+          me.focus();
+          if (e.keyCode == 13) callback(inp.value);
+        }
+      });
+      inp.focus();
+      CodeMirror.connect(inp, "blur", close);
+    }
+    return close;
+  });
+
+  CodeMirror.defineExtension("openConfirm", function(template, callbacks) {
+    var dialog = dialogDiv(this, template);
+    var buttons = dialog.getElementsByTagName("button");
+    var closed = false, me = this, blurring = 1;
+    function close() {
+      if (closed) return;
+      closed = true;
+      dialog.parentNode.removeChild(dialog);
+      me.focus();
+    }
+    buttons[0].focus();
+    for (var i = 0; i < buttons.length; ++i) {
+      var b = buttons[i];
+      (function(callback) {
+        CodeMirror.connect(b, "click", function(e) {
+          CodeMirror.e_preventDefault(e);
+          close();
+          if (callback) callback(me);
+        });
+      })(callbacks[i]);
+      CodeMirror.connect(b, "blur", function() {
+        --blurring;
+        setTimeout(function() { if (blurring <= 0) close(); }, 200);
+      });
+      CodeMirror.connect(b, "focus", function() { ++blurring; });
+    }
+  });
+})();
diff --git a/TestON/TAI/src/EditorScripts/error.png b/TestON/TAI/src/EditorScripts/error.png
new file mode 100644
index 0000000..8575b04
--- /dev/null
+++ b/TestON/TAI/src/EditorScripts/error.png
Binary files differ
diff --git a/TestON/TAI/src/EditorScripts/foldcode.js b/TestON/TAI/src/EditorScripts/foldcode.js
new file mode 100644
index 0000000..d91cba5
--- /dev/null
+++ b/TestON/TAI/src/EditorScripts/foldcode.js
@@ -0,0 +1,218 @@
+// the tagRangeFinder function is
+//   Copyright (C) 2011 by Daniel Glazman <daniel@glazman.org>
+// released under the MIT license (../../LICENSE) like the rest of CodeMirror
+CodeMirror.tagRangeFinder = function(cm, line, hideEnd) {
+  var nameStartChar = "A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD";
+  var nameChar = nameStartChar + "\-\.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
+  var xmlNAMERegExp = new RegExp("^[" + nameStartChar + "][" + nameChar + "]*");
+
+  var lineText = cm.getLine(line);
+  var found = false;
+  var tag = null;
+  var pos = 0;
+  while (!found) {
+    pos = lineText.indexOf("<", pos);
+    if (-1 == pos) // no tag on line
+      return;
+    if (pos + 1 < lineText.length && lineText[pos + 1] == "/") { // closing tag
+      pos++;
+      continue;
+    }
+    // ok we weem to have a start tag
+    if (!lineText.substr(pos + 1).match(xmlNAMERegExp)) { // not a tag name...
+      pos++;
+      continue;
+    }
+    var gtPos = lineText.indexOf(">", pos + 1);
+    if (-1 == gtPos) { // end of start tag not in line
+      var l = line + 1;
+      var foundGt = false;
+      var lastLine = cm.lineCount();
+      while (l < lastLine && !foundGt) {
+        var lt = cm.getLine(l);
+        var gt = lt.indexOf(">");
+        if (-1 != gt) { // found a >
+          foundGt = true;
+          var slash = lt.lastIndexOf("/", gt);
+          if (-1 != slash && slash < gt) {
+            var str = lineText.substr(slash, gt - slash + 1);
+            if (!str.match( /\/\s*\>/ )) { // yep, that's the end of empty tag
+              if (hideEnd === true) l++;
+              return l;
+            }
+          }
+        }
+        l++;
+      }
+      found = true;
+    }
+    else {
+      var slashPos = lineText.lastIndexOf("/", gtPos);
+      if (-1 == slashPos) { // cannot be empty tag
+        found = true;
+        // don't continue
+      }
+      else { // empty tag?
+        // check if really empty tag
+        var str = lineText.substr(slashPos, gtPos - slashPos + 1);
+        if (!str.match( /\/\s*\>/ )) { // finally not empty
+          found = true;
+          // don't continue
+        }
+      }
+    }
+    if (found) {
+      var subLine = lineText.substr(pos + 1);
+      tag = subLine.match(xmlNAMERegExp);
+      if (tag) {
+        // we have an element name, wooohooo !
+        tag = tag[0];
+        // do we have the close tag on same line ???
+        if (-1 != lineText.indexOf("</" + tag + ">", pos)) // yep
+        {
+          found = false;
+        }
+        // we don't, so we have a candidate...
+      }
+      else
+        found = false;
+    
+    }
+    if (!found)
+      pos++;
+  }
+
+  if (found) {
+    var startTag = "(\\<\\/" + tag + "\\>)|(\\<" + tag + "\\>)|(\\<" + tag + "\\s)|(\\<" + tag + "$)";
+    var startTagRegExp = new RegExp(startTag, "g");
+    var endTag = "</" + tag + ">";
+    var depth = 1;
+    var l = line + 1;
+    var lastLine = cm.lineCount();
+    while (l < lastLine) {
+      lineText = cm.getLine(l);
+      var match = lineText.match(startTagRegExp);
+      if (match) {
+        for (var i = 0; i < match.length; i++) {
+          if (match[i] == endTag)
+            depth--;
+          else
+            depth++;
+          if (!depth) {
+            if (hideEnd === true) l++;
+            return l;
+          }
+        }
+      }
+      l++;
+    }
+    return;
+  }
+};
+
+CodeMirror.braceRangeFinder = function(cm, line, hideEnd) {
+  var lineText = cm.getLine(line);
+  var startChar = lineText.lastIndexOf(" ");
+  if (startChar < 0 || lineText.lastIndexOf(" ") > startChar) return;
+  var tokenType = cm.getTokenAt({line: line, ch: startChar}).className;
+  var count = 1, lastLine = cm.lineCount(), end;
+  outer: for (var i = line + 1; i < lastLine; ++i) {
+    var text = cm.getLine(i), pos = 0;
+    for (;;) {
+      var nextOpen = text.indexOf("", pos), nextClose = text.indexOf("", pos);
+      if (nextOpen < 0) nextOpen = text.length;
+      if (nextClose < 0) nextClose = text.length;
+      pos = Math.min(nextOpen, nextClose);
+      if (pos == text.length) break;
+      if (cm.getTokenAt({line: i, ch: pos + 1}).className == tokenType) {
+        if (pos == nextOpen) ++count;
+        else if (!--count) { end = i; break outer; }
+      }
+      ++pos;
+    }
+  }
+  if (end == null || end == line + 1) return;
+  if (hideEnd === true) end++;
+  return end;
+};
+
+CodeMirror.braceRangeFinde = function(cm, line, hideEnd) {
+  var lineText = cm.getLine(line);
+  var startChar = lineText.lastIndexOf("{");
+  if (startChar < 0 || lineText.lastIndexOf("}") > startChar) return;
+  var tokenType = cm.getTokenAt({line: line, ch: startChar}).className;
+  var count = 1, lastLine = cm.lineCount(), end;
+  outer: for (var i = line + 1; i < lastLine; ++i) {
+    var text = cm.getLine(i), pos = 0;
+    for (;;) {
+      var nextOpen = text.indexOf("{", pos), nextClose = text.indexOf("}", pos);
+      if (nextOpen < 0) nextOpen = text.length;
+      if (nextClose < 0) nextClose = text.length;
+      pos = Math.min(nextOpen, nextClose);
+      if (pos == text.length) break;
+      if (cm.getTokenAt({line: i, ch: pos + 1}).className == tokenType) {
+        if (pos == nextOpen) ++count;
+        else if (!--count) { end = i; break outer; }
+      }
+      ++pos;
+    }
+  }
+  if (end == null || end == line + 1) return;
+  if (hideEnd === true) end++;
+  return end;
+};
+
+CodeMirror.indentRangeFinder = function(cm, line) {
+  var tabSize = cm.getOption("tabSize");
+  var myIndent = cm.getLineHandle(line).indentation(tabSize), last;
+  for (var i = line + 1, end = cm.lineCount(); i < end; ++i) {
+    var handle = cm.getLineHandle(i);
+    if (!/^\s*$/.test(handle.text)) {
+      if (handle.indentation(tabSize) <= myIndent) break;
+      last = i;
+    }
+  }
+  if (!last) return null;
+  return last + 1;
+};
+
+CodeMirror.newFoldFunction = function(rangeFinder, markText, hideEnd) {
+  var folded = [];
+  if (markText == null) markText = '<div style="position: absolute; left: 2px; color:#600">&#x25bc;</div>%N%';
+
+  function isFolded(cm, n) {
+    for (var i = 0; i < folded.length; ++i) {
+      var start = cm.lineInfo(folded[i].start);
+      if (!start) folded.splice(i--, 1);
+      else if (start.line == n) return {pos: i, region: folded[i]};
+    }
+  }
+
+  function expand(cm, region) {
+    cm.clearMarker(region.start);
+    for (var i = 0; i < region.hidden.length; ++i)
+      cm.showLine(region.hidden[i]);
+  }
+
+  return function(cm, line) {
+    cm.operation(function() {
+      var known = isFolded(cm, line);
+      if (known) {
+        folded.splice(known.pos, 1);
+        expand(cm, known.region);
+      } else {
+        var end = rangeFinder(cm, line, hideEnd);
+        if (end == null) return;
+        var hidden = [];
+        for (var i = line + 1; i < end; ++i) {
+          var handle = cm.hideLine(i);
+          if (handle) hidden.push(handle);
+        }
+        var first = cm.setMarker(line, markText);
+        var region = {start: first, hidden: hidden};
+        cm.onDeleteLine(first, function() { expand(cm, region); });
+        folded.push(region);
+      }
+    });
+  };
+};
diff --git a/TestON/TAI/src/EditorScripts/index.html b/TestON/TAI/src/EditorScripts/index.html
new file mode 100644
index 0000000..d536c42
--- /dev/null
+++ b/TestON/TAI/src/EditorScripts/index.html
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+    <title>Apache Tomcat</title>
+</head>
+
+<body>
+<h1>It works !</h1>
+
+<p>If you're seeing this page via a web browser, it means you've setup Tomcat successfully. Congratulations!</p>
+ 
+<p>This is the default Tomcat home page. It can be found on the local filesystem at: <code>/var/lib/tomcat6/webapps/ROOT/index.html</code></p>
+
+<p>Tomcat6 veterans might be pleased to learn that this system instance of Tomcat is installed with <code>CATALINA_HOME</code> in <code>/usr/share/tomcat6</code> and <code>CATALINA_BASE</code> in <code>/var/lib/tomcat6</code>, following the rules from <code>/usr/share/doc/tomcat6-common/RUNNING.txt.gz</code>.</p>
+
+<p>You might consider installing the following packages, if you haven't already done so:</p>
+
+<p><b>tomcat6-docs</b>: This package installs a web application that allows to browse the Tomcat 6 documentation locally. Once installed, you can access it by clicking <a href="docs/">here</a>.</p>
+
+<p><b>tomcat6-examples</b>: This package installs a web application that allows to access the Tomcat 6 Servlet and JSP examples. Once installed, you can access it by clicking <a href="examples/">here</a>.</p>
+
+<p><b>tomcat6-admin</b>: This package installs two web applications that can help managing this Tomcat instance. Once installed, you can access the <a href="manager/html">manager webapp</a> and the <a href="host-manager/html">host-manager webapp</a>.<p>
+
+<p>NOTE: For security reasons, using the manager webapp is restricted to users with role "manager". The host-manager webapp is restricted to users with role "admin". Users are defined in <code>/etc/tomcat6/tomcat-users.xml</code>.</p>
+
+</body>
+</html>
diff --git a/TestON/TAI/src/EditorScripts/info.jpg b/TestON/TAI/src/EditorScripts/info.jpg
new file mode 100644
index 0000000..9bfb6df
--- /dev/null
+++ b/TestON/TAI/src/EditorScripts/info.jpg
Binary files differ
diff --git a/TestON/TAI/src/EditorScripts/javascript-hint.css b/TestON/TAI/src/EditorScripts/javascript-hint.css
new file mode 100644
index 0000000..3af0790
--- /dev/null
+++ b/TestON/TAI/src/EditorScripts/javascript-hint.css
@@ -0,0 +1,135 @@
+(function () {
+  function forEach(arr, f) {
+    for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
+  }
+  
+  function arrayContains(arr, item) {
+    if (!Array.prototype.indexOf) {
+      var i = arr.length;
+      while (i--) {
+        if (arr[i] === item) {
+          return true;
+        }
+      }
+      return false;
+    }
+    return arr.indexOf(item) != -1;
+  }
+
+  function scriptHint(editor, keywords, getToken) {
+    // Find the token at the cursor
+    var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token;
+    // If it's not a 'word-style' token, ignore the token.
+		if (!/^[\w$_]*$/.test(token.string)) {
+      token = tprop = {start: cur.ch, end: cur.ch, string: "", state: token.state,
+                       className: token.string == "." ? "property" : null};
+    }
+    // If it is a property, find out what it is a property of.
+    while (tprop.className == "property") {
+      tprop = getToken(editor, {line: cur.line, ch: tprop.start});
+      if (tprop.string != ".") return;
+      tprop = getToken(editor, {line: cur.line, ch: tprop.start});
+      if (tprop.string == ')') {
+        var level = 1;
+        do {
+          tprop = getToken(editor, {line: cur.line, ch: tprop.start});
+          switch (tprop.string) {
+          case ')': level++; break;
+          case '(': level--; break;
+          default: break;
+          }
+        } while (level > 0)
+        tprop = getToken(editor, {line: cur.line, ch: tprop.start});
+				if (tprop.className == 'variable')
+					tprop.className = 'function';
+				else return; // no clue
+      }
+      if (!context) var context = [];
+      context.push(tprop);
+    }
+    return {list: getCompletions(token, context, keywords),
+            from: {line: cur.line, ch: token.start},
+            to: {line: cur.line, ch: token.end}};
+  }
+
+  CodeMirror.javascriptHint = function(editor) {
+    return scriptHint(editor, javascriptKeywords,
+                      function (e, cur) {return e.getTokenAt(cur);});
+  }
+
+  function getCoffeeScriptToken(editor, cur) {
+  // This getToken, it is for coffeescript, imitates the behavior of
+  // getTokenAt method in javascript.js, that is, returning "property"
+  // type and treat "." as indepenent token.
+    var token = editor.getTokenAt(cur);
+    if (cur.ch == token.start + 1 && token.string.charAt(0) == '.') {
+      token.end = token.start;
+      token.string = '.';
+      token.className = "property";
+    }
+    else if (/^\.[\w$_]*$/.test(token.string)) {
+      token.className = "property";
+      token.start++;
+      token.string = token.string.replace(/\./, '');
+    }
+    return token;
+  }
+
+  CodeMirror.coffeescriptHint = function(editor) {
+    return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken);
+  }
+
+  var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " +
+                     "toUpperCase toLowerCase split concat match replace search").split(" ");
+  var arrayProps = ("length concat join splice push pop shift unshift slice reverse sort indexOf " +
+                    "lastIndexOf every some filter forEach map reduce reduceRight ").split(" ");
+  var funcProps = "prototype apply call bind".split(" ");
+  var javascriptKeywords = ("break case catch continue debugger default delete do else false finally for function " +
+                  "if in instanceof new null return switch throw true try typeof var void while with").split(" ");
+  var coffeescriptKeywords = ("and break catch class continue delete do else extends false finally for " +
+                  "if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes").split(" ");
+
+  function getCompletions(token, context, keywords) {
+    var found = [], start = token.string;
+    function maybeAdd(str) {
+      if (str.indexOf(start) == 0 && !arrayContains(found, str)) found.push(str);
+    }
+    function gatherCompletions(obj) {
+      if (typeof obj == "string") forEach(stringProps, maybeAdd);
+      else if (obj instanceof Array) forEach(arrayProps, maybeAdd);
+      else if (obj instanceof Function) forEach(funcProps, maybeAdd);
+      for (var name in obj) maybeAdd(name);
+    }
+
+    if (context) {
+      // If this is a property, see if it belongs to some object we can
+      // find in the current environment.
+      var obj = context.pop(), base;
+      if (obj.className == "variable")
+        base = window[obj.string];
+      else if (obj.className == "string")
+        base = "";
+      else if (obj.className == "atom")
+        base = 1;
+      else if (obj.className == "function") {
+        if (window.jQuery != null && (obj.string == '$' || obj.string == 'jQuery') &&
+            (typeof window.jQuery == 'function'))
+          base = window.jQuery();
+        else if (window._ != null && (obj.string == '_') && (typeof window._ == 'function'))
+          base = window._();
+      }
+      while (base != null && context.length)
+        base = base[context.pop().string];
+      if (base != null) gatherCompletions(base);
+    }
+    else {
+      // If not, just look in the window object and any local scope
+      // (reading into JS mode internals to get at the local variables)
+      for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name);
+      gatherCompletions(window);
+      forEach(keywords, maybeAdd);
+    }
+    return found;
+  }
+})();
+
diff --git a/TestON/TAI/src/EditorScripts/javascript-hint.js b/TestON/TAI/src/EditorScripts/javascript-hint.js
new file mode 100644
index 0000000..2117e5a
--- /dev/null
+++ b/TestON/TAI/src/EditorScripts/javascript-hint.js
@@ -0,0 +1,134 @@
+(function () {
+  function forEach(arr, f) {
+    for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
+  }
+  
+  function arrayContains(arr, item) {
+    if (!Array.prototype.indexOf) {
+      var i = arr.length;
+      while (i--) {
+        if (arr[i] === item) {
+          return true;
+        }
+      }
+      return false;
+    }
+    return arr.indexOf(item) != -1;
+  }
+
+  function scriptHint(editor, keywords, getToken) {
+    // Find the token at the cursor
+    var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token;
+    // If it's not a 'word-style' token, ignore the token.
+		if (!/^[\w$_]*$/.test(token.string)) {
+      token = tprop = {start: cur.ch, end: cur.ch, string: "", state: token.state,
+                       className: token.string == "." ? "property" : null};
+    }
+    // If it is a property, find out what it is a property of.
+    while (tprop.className == "property") {
+      tprop = getToken(editor, {line: cur.line, ch: tprop.start});
+      if (tprop.string != ".") return;
+      tprop = getToken(editor, {line: cur.line, ch: tprop.start});
+      if (tprop.string == ')') {
+        var level = 1;
+        do {
+          tprop = getToken(editor, {line: cur.line, ch: tprop.start});
+          switch (tprop.string) {
+          case ')': level++; break;
+          case '(': level--; break;
+          default: break;
+          }
+        } while (level > 0)
+        tprop = getToken(editor, {line: cur.line, ch: tprop.start});
+				if (tprop.className == 'variable')
+					tprop.className = 'function';
+				else return; // no clue
+      }
+      if (!context) var context = [];
+      context.push(tprop);
+    }
+    return {list: getCompletions(token, context, keywords),
+            from: {line: cur.line, ch: token.start},
+            to: {line: cur.line, ch: token.end}};
+  }
+
+  CodeMirror.javascriptHint = function(editor) {
+    return scriptHint(editor, javascriptKeywords,
+                      function (e, cur) {return e.getTokenAt(cur);});
+  }
+
+  function getCoffeeScriptToken(editor, cur) {
+  // This getToken, it is for coffeescript, imitates the behavior of
+  // getTokenAt method in javascript.js, that is, returning "property"
+  // type and treat "." as indepenent token.
+    var token = editor.getTokenAt(cur);
+    if (cur.ch == token.start + 1 && token.string.charAt(0) == '.') {
+      token.end = token.start;
+      token.string = '.';
+      token.className = "property";
+    }
+    else if (/^\.[\w$_]*$/.test(token.string)) {
+      token.className = "property";
+      token.start++;
+      token.string = token.string.replace(/\./, '');
+    }
+    return token;
+  }
+
+  CodeMirror.coffeescriptHint = function(editor) {
+    return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken);
+  }
+
+  var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " +
+                     "toUpperCase toLowerCase split concat match replace search").split(" ");
+  var arrayProps = ("length concat join splice push pop shift unshift slice reverse sort indexOf " +
+                    "lastIndexOf every some filter forEach map reduce reduceRight ").split(" ");
+  var funcProps = "prototype apply call bind".split(" ");
+  var javascriptKeywords = ("break case catch continue debugger default delete do else false finally for function " +
+                  "if in instanceof new null return switch throw true try typeof var void while with").split(" ");
+  var coffeescriptKeywords = ("and break catch class continue delete do else extends false finally for " +
+                  "if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes").split(" ");
+
+  function getCompletions(token, context, keywords) {
+    var found = [], start = token.string;
+    function maybeAdd(str) {
+      if (str.indexOf(start) == 0 && !arrayContains(found, str)) found.push(str);
+    }
+    function gatherCompletions(obj) {
+      if (typeof obj == "string") forEach(stringProps, maybeAdd);
+      else if (obj instanceof Array) forEach(arrayProps, maybeAdd);
+      else if (obj instanceof Function) forEach(funcProps, maybeAdd);
+      for (var name in obj) maybeAdd(name);
+    }
+
+    if (context) {
+      // If this is a property, see if it belongs to some object we can
+      // find in the current environment.
+      var obj = context.pop(), base;
+      if (obj.className == "variable")
+        base = window[obj.string];
+      else if (obj.className == "string")
+        base = "";
+      else if (obj.className == "atom")
+        base = 1;
+      else if (obj.className == "function") {
+        if (window.jQuery != null && (obj.string == '$' || obj.string == 'jQuery') &&
+            (typeof window.jQuery == 'function'))
+          base = window.jQuery();
+        else if (window._ != null && (obj.string == '_') && (typeof window._ == 'function'))
+          base = window._();
+      }
+      while (base != null && context.length)
+        base = base[context.pop().string];
+      if (base != null) gatherCompletions(base);
+    }
+    else {
+      // If not, just look in the window object and any local scope
+      // (reading into JS mode internals to get at the local variables)
+      for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name);
+      gatherCompletions(window);
+      forEach(keywords, maybeAdd);
+    }
+    return found;
+  }
+})();
diff --git a/TestON/TAI/src/EditorScripts/javascript.js b/TestON/TAI/src/EditorScripts/javascript.js
new file mode 100644
index 0000000..9ac5a70
--- /dev/null
+++ b/TestON/TAI/src/EditorScripts/javascript.js
@@ -0,0 +1,361 @@
+CodeMirror.defineMode("javascript", function(config, parserConfig) {
+  var indentUnit = config.indentUnit;
+  var jsonMode = parserConfig.json;
+
+  // Tokenizer
+
+  var keywords = function(){
+    function kw(type) {return {type: type, style: "keyword"};}
+    var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
+    var operator = kw("operator"), atom = {type: "atom", style: "atom"};
+    return {
+      "if": A, "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
+      "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C,
+      "var": kw("var"), "const": kw("var"), "let": kw("var"),
+      "function": kw("function"), "catch": kw("catch"),
+      "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
+      "in": operator, "typeof": operator, "instanceof": operator,
+      "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,"CASE":A,"END CASE":A
+    };
+  }();
+
+  var isOperatorChar = /[+\-*&%=<>!?|]/;
+
+  function chain(stream, state, f) {
+    state.tokenize = f;
+    return f(stream, state);
+  }
+
+  function nextUntilUnescaped(stream, end) {
+    var escaped = false, next;
+    while ((next = stream.next()) != null) {
+      if (next == end && !escaped)
+        return false;
+      escaped = !escaped && next == "\\";
+    }
+    return escaped;
+  }
+
+  // Used as scratch variables to communicate multiple values without
+  // consing up tons of objects.
+  var type, content;
+  function ret(tp, style, cont) {
+    type = tp; content = cont;
+    return style;
+  }
+
+  function jsTokenBase(stream, state) {
+    var ch = stream.next();
+    if (ch == '"' || ch == "'")
+      return chain(stream, state, jsTokenString(ch));
+    else if (/[\[\]{}\(\),;\:\.]/.test(ch))
+      return ret(ch);
+    else if (ch == "0" && stream.eat(/x/i)) {
+      stream.eatWhile(/[\da-f]/i);
+      return ret("number", "number");
+    }      
+    else if (/\d/.test(ch)) {
+      stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
+      return ret("number", "number");
+    }
+    else if (ch == "/") {
+      if (stream.eat("*")) {
+        return chain(stream, state, jsTokenComment);
+      }
+      else if (stream.eat("/")) {
+        stream.skipToEnd();
+        return ret("comment", "comment");
+      }
+      else if (state.reAllowed) {
+        nextUntilUnescaped(stream, "/");
+        stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
+        return ret("regexp", "string-2");
+      }
+      else {
+        stream.eatWhile(isOperatorChar);
+        return ret("operator", null, stream.current());
+      }
+    }
+    else if (ch == "#") {
+        stream.skipToEnd();
+        return ret("error", "error");
+    }
+    else if (isOperatorChar.test(ch)) {
+      stream.eatWhile(isOperatorChar);
+      return ret("operator", null, stream.current());
+    }
+    else {
+      stream.eatWhile(/[\w\$_]/);
+      var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
+      return (known && state.kwAllowed) ? ret(known.type, known.style, word) :
+                     ret("variable", "variable", word);
+    }
+  }
+
+  function jsTokenString(quote) {
+    return function(stream, state) {
+      if (!nextUntilUnescaped(stream, quote))
+        state.tokenize = jsTokenBase;
+      return ret("string", "string");
+    };
+  }
+
+  function jsTokenComment(stream, state) {
+    var maybeEnd = false, ch;
+    while (ch = stream.next()) {
+      if (ch == "/" && maybeEnd) {
+        state.tokenize = jsTokenBase;
+        break;
+      }
+      maybeEnd = (ch == "*");
+    }
+    return ret("comment", "comment");
+  }
+
+  // Parser
+
+  var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true};
+
+  function JSLexical(indented, column, type, align, prev, info) {
+    this.indented = indented;
+    this.column = column;
+    this.type = type;
+    this.prev = prev;
+    this.info = info;
+    if (align != null) this.align = align;
+  }
+
+  function inScope(state, varname) {
+    for (var v = state.localVars; v; v = v.next)
+      if (v.name == varname) return true;
+  }
+
+  function parseJS(state, style, type, content, stream) {
+    var cc = state.cc;
+    // Communicate our context to the combinators.
+    // (Less wasteful than consing up a hundred closures on every call.)
+    cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
+  
+    if (!state.lexical.hasOwnProperty("align"))
+      state.lexical.align = true;
+
+    while(true) {
+      var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
+      if (combinator(type, content)) {
+        while(cc.length && cc[cc.length - 1].lex)
+          cc.pop()();
+        if (cx.marked) return cx.marked;
+        if (type == "variable" && inScope(state, content)) return "variable-2";
+        return style;
+      }
+    }
+  }
+
+  // Combinator utils
+
+  var cx = {state: null, column: null, marked: null, cc: null};
+  function pass() {
+    for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
+  }
+  function cont() {
+    pass.apply(null, arguments);
+    return true;
+  }
+  function register(varname) {
+    var state = cx.state;
+    if (state.context) {
+      cx.marked = "def";
+      for (var v = state.localVars; v; v = v.next)
+        if (v.name == varname) return;
+      state.localVars = {name: varname, next: state.localVars};
+    }
+  }
+
+  // Combinators
+
+  var defaultVars = {name: "this", next: {name: "arguments"}};
+  function pushcontext() {
+    if (!cx.state.context) cx.state.localVars = defaultVars;
+    cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
+  }
+  function popcontext() {
+    cx.state.localVars = cx.state.context.vars;
+    cx.state.context = cx.state.context.prev;
+  }
+  function pushlex(type, info) {
+    var result = function() {
+      var state = cx.state;
+      state.lexical = new JSLexical(state.indented, cx.stream.column(), type, null, state.lexical, info)
+    };
+    result.lex = true;
+    return result;
+  }
+  function poplex() {
+    var state = cx.state;
+    if (state.lexical.prev) {
+      if (state.lexical.type == ")")
+        state.indented = state.lexical.indented;
+      state.lexical = state.lexical.prev;
+    }
+  }
+  poplex.lex = true;
+
+  function expect(wanted) {
+    return function expecting(type) {
+      if (type == wanted) return cont();
+      else if (wanted == ";") return pass();
+      else return cont(arguments.callee);
+    };
+  }
+
+  function statement(type) {
+    if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex);
+    if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
+    if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
+    if (type == "{") return cont(pushlex("}"), block, poplex);
+    if (type == ";") return cont();
+    if (type == "function") return cont(functiondef);
+    if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
+                                      poplex, statement, poplex);
+    if (type == "variable") return cont(pushlex("stat"), maybelabel);
+    if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
+                                         block, poplex, poplex);
+    if (type == "case") return cont(expression, expect(":"));
+    if (type == "default") return cont(expect(":"));
+    if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
+                                        statement, poplex, popcontext);
+    return pass(pushlex("stat"), expression, expect(";"), poplex);
+  }
+  function expression(type) {
+    if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator);
+    if (type == "function") return cont(functiondef);
+    if (type == "keyword c") return cont(maybeexpression);
+    if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeoperator);
+    if (type == "operator") return cont(expression);
+    if (type == "[") return cont(pushlex("]"), commasep(expression, "]"), poplex, maybeoperator);
+    if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator);
+    return cont();
+  }
+  function maybeexpression(type) {
+    if (type.match(/[;\}\)\],]/)) return pass();
+    return pass(expression);
+  }
+    
+  function maybeoperator(type, value) {
+    if (type == "operator" && /\+\+|--/.test(value)) return cont(maybeoperator);
+    if (type == "operator" || type == ":") return cont(expression);
+    if (type == ";") return;
+    if (type == "(") return cont(pushlex(")"), commasep(expression, ")"), poplex, maybeoperator);
+    if (type == ".") return cont(property, maybeoperator);
+    if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator);
+  }
+  function maybelabel(type) {
+    if (type == ":") return cont(poplex, statement);
+    return pass(maybeoperator, expect(";"), poplex);
+  }
+  function property(type) {
+    if (type == "variable") {cx.marked = "property"; return cont();}
+  }
+  function objprop(type) {
+    if (type == "variable") cx.marked = "property";
+    if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expression);
+  }
+  function commasep(what, end) {
+    function proceed(type) {
+      if (type == ",") return cont(what, proceed);
+      if (type == end) return cont();
+      return cont(expect(end));
+    }
+    return function commaSeparated(type) {
+      if (type == end) return cont();
+      else return pass(what, proceed);
+    };
+  }
+  function block(type) {
+    if (type == "}") return cont();
+    return pass(statement, block);
+  }
+  function vardef1(type, value) {
+    if (type == "variable"){register(value); return cont(vardef2);}
+    return cont();
+  }
+  function vardef2(type, value) {
+    if (value == "=") return cont(expression, vardef2);
+    if (type == ",") return cont(vardef1);
+  }
+  function forspec1(type) {
+    if (type == "var") return cont(vardef1, forspec2);
+    if (type == ";") return pass(forspec2);
+    if (type == "variable") return cont(formaybein);
+    return pass(forspec2);
+  }
+  function formaybein(type, value) {
+    if (value == "in") return cont(expression);
+    return cont(maybeoperator, forspec2);
+  }
+  function forspec2(type, value) {
+    if (type == ";") return cont(forspec3);
+    if (value == "in") return cont(expression);
+    return cont(expression, expect(";"), forspec3);
+  }
+  function forspec3(type) {
+    if (type != ")") cont(expression);
+  }
+  function functiondef(type, value) {
+    if (type == "variable") {register(value); return cont(functiondef);}
+    if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext);
+  }
+  function funarg(type, value) {
+    if (type == "variable") {register(value); return cont();}
+  }
+
+  // Interface
+
+  return {
+    startState: function(basecolumn) {
+      return {
+        tokenize: jsTokenBase,
+        reAllowed: true,
+        kwAllowed: true,
+        cc: [],
+        lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
+        localVars: parserConfig.localVars,
+        context: parserConfig.localVars && {vars: parserConfig.localVars},
+        indented: 0
+      };
+    },
+
+    token: function(stream, state) {
+      if (stream.sol()) {
+        if (!state.lexical.hasOwnProperty("align"))
+          state.lexical.align = false;
+        state.indented = stream.indentation();
+      }
+      if (stream.eatSpace()) return null;
+      var style = state.tokenize(stream, state);
+      if (type == "comment") return style;
+      state.reAllowed = !!(type == "operator" || type == "keyword c" || type.match(/^[\[{}\(,;:]$/));
+      state.kwAllowed = type != '.';
+      return parseJS(state, style, type, content, stream);
+    },
+
+    indent: function(state, textAfter) {
+      if (state.tokenize != jsTokenBase) return 0;
+      var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
+      if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
+      var type = lexical.type, closing = firstChar == type;
+      if (type == "vardef") return lexical.indented + 4;
+      else if (type == "form" && firstChar == "{") return lexical.indented;
+      else if (type == "stat" || type == "form") return lexical.indented + indentUnit;
+      else if (lexical.info == "switch" && !closing)
+        return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
+      else if (lexical.align) return lexical.column + (closing ? 0 : 1);
+      else return lexical.indented + (closing ? 0 : indentUnit);
+    },
+
+    electricChars: ":{}"
+  };
+});
+
+CodeMirror.defineMIME("text/javascript", "javascript");
+CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
diff --git a/TestON/TAI/src/EditorScripts/match-highlighter.js b/TestON/TAI/src/EditorScripts/match-highlighter.js
new file mode 100644
index 0000000..59098ff
--- /dev/null
+++ b/TestON/TAI/src/EditorScripts/match-highlighter.js
@@ -0,0 +1,44 @@
+// Define match-highlighter commands. Depends on searchcursor.js
+// Use by attaching the following function call to the onCursorActivity event:
+	//myCodeMirror.matchHighlight(minChars);
+// And including a special span.CodeMirror-matchhighlight css class (also optionally a separate one for .CodeMirror-focused -- see demo matchhighlighter.html)
+
+(function() {
+  var DEFAULT_MIN_CHARS = 2;
+  
+  function MatchHighlightState() {
+	this.marked = [];
+  }
+  function getMatchHighlightState(cm) {
+	return cm._matchHighlightState || (cm._matchHighlightState = new MatchHighlightState());
+  }
+  
+  function clearMarks(cm) {
+	var state = getMatchHighlightState(cm);
+	for (var i = 0; i < state.marked.length; ++i)
+		state.marked[i].clear();
+	state.marked = [];
+  }
+  
+  function markDocument(cm, className, minChars) {
+    clearMarks(cm);
+	minChars = (typeof minChars !== 'undefined' ? minChars : DEFAULT_MIN_CHARS);
+	if (cm.somethingSelected() && cm.getSelection().replace(/^\s+|\s+$/g, "").length >= minChars) {
+		var state = getMatchHighlightState(cm);
+		var query = cm.getSelection();
+		cm.operation(function() {
+			if (cm.lineCount() < 2000) { // This is too expensive on big documents.
+			  for (var cursor = cm.getSearchCursor(query); cursor.findNext();) {
+				//Only apply matchhighlight to the matches other than the one actually selected
+				if (!(cursor.from().line === cm.getCursor(true).line && cursor.from().ch === cm.getCursor(true).ch))
+					state.marked.push(cm.markText(cursor.from(), cursor.to(), className));
+			  }
+			}
+		  });
+	}
+  }
+
+  CodeMirror.defineExtension("matchHighlight", function(className, minChars) {
+    markDocument(this, className, minChars);
+  });
+})();
diff --git a/TestON/TAI/src/EditorScripts/perl.js b/TestON/TAI/src/EditorScripts/perl.js
new file mode 100644
index 0000000..d750099
--- /dev/null
+++ b/TestON/TAI/src/EditorScripts/perl.js
@@ -0,0 +1,979 @@
+// CodeMirror2 mode/perl/perl.js (text/x-perl) beta 0.10 (2011-11-08)
+// This is a part of CodeMirror from https://github.com/sabaca/CodeMirror_mode_perl (mail@sabaca.com)
+CodeMirror.defineMode("perl",function(config,parserConfig){
+	// http://perldoc.perl.org
+	var PERL={				    	//   null - magic touch
+							//   1 - keyword
+							//   2 - def
+							//   3 - atom
+							//   4 - operator
+							//   5 - variable-2 (predefined)
+							//   [x,y] - x=1,2,3; y=must be defined if x{...}
+						//	PERL operators
+		'->'				:   4,
+		'++'				:   4,
+		'--'				:   4,
+		'**'				:   4,
+							//   ! ~ \ and unary + and -
+		'=~'				:   4,
+		'!~'				:   4,
+		'*'				:   4,
+		'/'				:   4,
+		'%'				:   4,
+		'x'				:   4,
+		'+'				:   4,
+		'-'				:   4,
+		'.'				:   4,
+		'<<'				:   4,
+		'>>'				:   4,
+							//   named unary operators
+		'<'				:   4,
+		'>'				:   4,
+		'<='				:   4,
+		'>='				:   4,
+		'lt'				:   4,
+		'gt'				:   4,
+		'le'				:   4,
+		'ge'				:   4,
+		'=='				:   4,
+		'!='				:   4,
+		'<=>'				:   4,
+		'eq'				:   4,
+		'ne'				:   4,
+		'cmp'				:   4,
+		'~~'				:   4,
+		'&'				:   4,
+		'|'				:   4,
+		'^'				:   4,
+		'&&'				:   4,
+		'||'				:   4,
+		'//'				:   4,
+		'..'				:   4,
+		'...'				:   4,
+		'?'				:   4,
+		':'				:   4,
+		'='				:   4,
+		'+='				:   4,
+		'-='				:   4,
+		'*='				:   4,	//   etc. ???
+		','				:   4,
+		'=>'				:   4,
+		'::'				:   4,
+				   			//   list operators (rightward)
+		'not'				:   4,
+		'and'				:   4,
+		'or'				:   4,
+		'xor'				:   4,
+						//	PERL predefined variables (I know, what this is a paranoid idea, but may be needed for people, who learn PERL, and for me as well, ...and may be for you?;)
+		'BEGIN'				:   [5,1],
+		'CASE'				:   [5,1],
+		'END'                           :    [5,1],
+		'PRINT'				:   [5,1],
+		'PRINTF'			:   [5,1],
+		'GETC'				:   [5,1],
+		'READ'				:   [5,1],
+		'READLINE'			:   [5,1],
+		'DESTROY'			:   [5,1],
+		'TIE'				:   [5,1],
+		'TIEHANDLE'			:   [5,1],
+		'UNTIE'				:   [5,1],
+		'STDIN'				:    5,
+		'STDIN_TOP'			:    5,
+		'STDOUT'			:    5,
+		'STDOUT_TOP'			:    5,
+		'STDERR'			:    5,
+		'STDERR_TOP'			:    5,
+		'$ARG'				:    5,
+		'$_'				:    5,
+		'@ARG'				:    5,
+		'@_'				:    5,
+		'$LIST_SEPARATOR'		:    5,
+		'$"'				:    5,
+		'$PROCESS_ID'			:    5,
+		'$PID'				:    5,
+		'$$'				:    5,
+		'$REAL_GROUP_ID'		:    5,
+		'$GID'				:    5,
+		'$('				:    5,
+		'$EFFECTIVE_GROUP_ID'		:    5,
+		'$EGID'				:    5,
+		'$)'				:    5,
+		'$PROGRAM_NAME'			:    5,
+		'$0'				:    5,
+		'$SUBSCRIPT_SEPARATOR'		:    5,
+		'$SUBSEP'			:    5,
+		'$;'				:    5,
+		'$REAL_USER_ID'			:    5,
+		'$UID'				:    5,
+		'$<'				:    5,
+		'$EFFECTIVE_USER_ID'		:    5,
+		'$EUID'				:    5,
+		'$>'				:    5,
+		'$a'				:    5,
+		'$b'				:    5,
+		'$COMPILING'			:    5,
+		'$^C'				:    5,
+		'$DEBUGGING'			:    5,
+		'$^D'				:    5,
+		'${^ENCODING}'			:    5,
+		'$ENV'				:    5,
+		'%ENV'				:    5,
+		'$SYSTEM_FD_MAX'		:    5,
+		'$^F'				:    5,
+		'@F'				:    5,
+		'${^GLOBAL_PHASE}'		:    5,
+		'$^H'				:    5,
+		'%^H'				:    5,
+		'@INC'				:    5,
+		'%INC'				:    5,
+		'$INPLACE_EDIT'			:    5,
+		'$^I'				:    5,
+		'$^M'				:    5,
+		'$OSNAME'			:    5,
+		'$^O'				:    5,
+		'${^OPEN}'			:    5,
+		'$PERLDB'			:    5,
+		'$^P'				:    5,
+		'$SIG'				:    5,
+		'%SIG'				:    5,
+		'$BASETIME'			:    5,
+		'$^T'				:    5,
+		'${^TAINT}'			:    5,
+		'${^UNICODE}'			:    5,
+		'${^UTF8CACHE}'			:    5,
+		'${^UTF8LOCALE}'		:    5,
+		'$PERL_VERSION'			:    5,
+		'$^V'				:    5,
+		'${^WIN32_SLOPPY_STAT}'		:    5,
+		'$EXECUTABLE_NAME'		:    5,
+		'$^X'				:    5,
+		'$1'				:    5,	// - regexp $1, $2...
+		'$MATCH'			:    5,
+		'$&'				:    5,
+		'${^MATCH}'			:    5,
+		'$PREMATCH'			:    5,
+		'$`'				:    5,
+		'${^PREMATCH}'			:    5,
+		'$POSTMATCH'			:    5,
+		"$'"				:    5,
+		'${^POSTMATCH}'			:    5,
+		'$LAST_PAREN_MATCH'		:    5,
+		'$+'				:    5,
+		'$LAST_SUBMATCH_RESULT'		:    5,
+		'$^N'				:    5,
+		'@LAST_MATCH_END'		:    5,
+		'@+'				:    5,
+		'%LAST_PAREN_MATCH'		:    5,
+		'%+'				:    5,
+		'@LAST_MATCH_START'		:    5,
+		'@-'				:    5,
+		'%LAST_MATCH_START'		:    5,
+		'%-'				:    5,
+		'$LAST_REGEXP_CODE_RESULT'	:    5,
+		'$^R'				:    5,
+		'${^RE_DEBUG_FLAGS}'		:    5,
+		'${^RE_TRIE_MAXBUF}'		:    5,
+		'$ARGV'				:    5,
+		'@ARGV'				:    5,
+		'ARGV'				:    5,
+		'ARGVOUT'			:    5,
+		'$OUTPUT_FIELD_SEPARATOR'	:    5,
+		'$OFS'				:    5,
+		'$,'				:    5,
+		'$INPUT_LINE_NUMBER'		:    5,
+		'$NR'				:    5,
+		'$.'				:    5,
+		'$INPUT_RECORD_SEPARATOR'	:    5,
+		'$RS'				:    5,
+		'$/'				:    5,
+		'$OUTPUT_RECORD_SEPARATOR'	:    5,
+		'$ORS'				:    5,
+		'$\\'				:    5,
+		'$OUTPUT_AUTOFLUSH'		:    5,
+		'$|'				:    5,
+		'$ACCUMULATOR'			:    5,
+		'$^A'				:    5,
+		'$FORMAT_FORMFEED'		:    5,
+		'$^L'				:    5,
+		'$FORMAT_PAGE_NUMBER'		:    5,
+		'$%'				:    5,
+		'$FORMAT_LINES_LEFT'		:    5,
+		'$-'				:    5,
+		'$FORMAT_LINE_BREAK_CHARACTERS'	:    5,
+		'$:'				:    5,
+		'$FORMAT_LINES_PER_PAGE'	:    5,
+		'$='				:    5,
+		'$FORMAT_TOP_NAME'		:    5,
+		'$^'				:    5,
+		'$FORMAT_NAME'			:    5,
+		'$~'				:    5,
+		'${^CHILD_ERROR_NATIVE}'	:    5,
+		'$EXTENDED_OS_ERROR'		:    5,
+		'$^E'				:    5,
+		'$EXCEPTIONS_BEING_CAUGHT'	:    5,
+		'$^S'				:    5,
+		'$WARNING'			:    5,
+		'$^W'				:    5,
+		'${^WARNING_BITS}'		:    5,
+		'$OS_ERROR'			:    5,
+		'$ERRNO'			:    5,
+		'$!'				:    5,
+		'%OS_ERROR'			:    5,
+		'%ERRNO'			:    5,
+		'%!'				:    5,
+		'$CHILD_ERROR'			:    5,
+		'$?'				:    5,
+		'$EVAL_ERROR'			:    5,
+		'$@'				:    5,
+		'$OFMT'				:    5,
+		'$#'				:    5,
+		'$*'				:    5,
+		'$ARRAY_BASE'			:    5,
+		'$['				:    5,
+		'$OLD_PERL_VERSION'		:    5,
+		'$]'				:    5,
+						//	PERL blocks
+		'if'				:[1,1],
+		elsif				:[1,1],
+		'else'				:[1,1],
+		'while'				:[1,1],
+		unless				:[1,1],
+		'for'				:[1,1],
+		foreach				:[1,1],
+						//	PERL functions
+		'abs'				:1,	// - absolute value function
+		accept				:1,	// - accept an incoming socket connect
+		alarm				:1,	// - schedule a SIGALRM
+		'atan2'				:1,	// - arctangent of Y/X in the range -PI to PI
+		bind				:1,	// - binds an address to a socket
+		binmode				:1,	// - prepare binary files for I/O
+		bless				:1,	// - create an object
+		bootstrap			:1,	//
+		'break'				:1,	// - break out of a "given" block
+		caller				:1,	// - get context of the current subroutine call
+		chdir				:1,	// - change your current working directory
+		chmod				:1,	// - changes the permissions on a list of files
+		chomp				:1,	// - remove a trailing record separator from a string
+		chop				:1,	// - remove the last character from a string
+		chown				:1,	// - change the owership on a list of files
+		chr				:1,	// - get character this number represents
+		chroot				:1,	// - make directory new root for path lookups
+		close				:1,	// - close file (or pipe or socket) handle
+		closedir			:1,	// - close directory handle
+		connect				:1,	// - connect to a remote socket
+		'continue'			:[1,1],	// - optional trailing block in a while or foreach
+		'cos'				:1,	// - cosine function
+		crypt				:1,	// - one-way passwd-style encryption
+		dbmclose			:1,	// - breaks binding on a tied dbm file
+		dbmopen				:1,	// - create binding on a tied dbm file
+		'default'			:1,	//
+		defined				:1,	// - test whether a value, variable, or function is defined
+		'delete'			:1,	// - deletes a value from a hash
+		die				:1,	// - raise an exception or bail out
+		'do'				:1,	// - turn a BLOCK into a TERM
+		dump				:1,	// - create an immediate core dump
+		each				:1,	// - retrieve the next key/value pair from a hash
+		endgrent			:1,	// - be done using group file
+		endhostent			:1,	// - be done using hosts file
+		endnetent			:1,	// - be done using networks file
+		endprotoent			:1,	// - be done using protocols file
+		endpwent			:1,	// - be done using passwd file
+		endservent			:1,	// - be done using services file
+		eof				:1,	// - test a filehandle for its end
+		'eval'				:1,	// - catch exceptions or compile and run code
+		'exec'				:1,	// - abandon this program to run another
+		exists				:1,	// - test whether a hash key is present
+		exit				:1,	// - terminate this program
+		'exp'				:1,	// - raise I to a power
+		fcntl				:1,	// - file control system call
+		fileno				:1,	// - return file descriptor from filehandle
+		flock				:1,	// - lock an entire file with an advisory lock
+		fork				:1,	// - create a new process just like this one
+		format				:1,	// - declare a picture format with use by the write() function
+		formline			:1,	// - internal function used for formats
+		getc				:1,	// - get the next character from the filehandle
+		getgrent			:1,	// - get next group record
+		getgrgid			:1,	// - get group record given group user ID
+		getgrnam			:1,	// - get group record given group name
+		gethostbyaddr			:1,	// - get host record given its address
+		gethostbyname			:1,	// - get host record given name
+		gethostent			:1,	// - get next hosts record
+		getlogin			:1,	// - return who logged in at this tty
+		getnetbyaddr			:1,	// - get network record given its address
+		getnetbyname			:1,	// - get networks record given name
+		getnetent			:1,	// - get next networks record
+		getpeername			:1,	// - find the other end of a socket connection
+		getpgrp				:1,	// - get process group
+		getppid				:1,	// - get parent process ID
+		getpriority			:1,	// - get current nice value
+		getprotobyname			:1,	// - get protocol record given name
+		getprotobynumber		:1,	// - get protocol record numeric protocol
+		getprotoent			:1,	// - get next protocols record
+		getpwent			:1,	// - get next passwd record
+		getpwnam			:1,	// - get passwd record given user login name
+		getpwuid			:1,	// - get passwd record given user ID
+		getservbyname			:1,	// - get services record given its name
+		getservbyport			:1,	// - get services record given numeric port
+		getservent			:1,	// - get next services record
+		getsockname			:1,	// - retrieve the sockaddr for a given socket
+		getsockopt			:1,	// - get socket options on a given socket
+		given				:1,	//
+		glob				:1,	// - expand filenames using wildcards
+		gmtime				:1,	// - convert UNIX time into record or string using Greenwich time
+		'goto'				:1,	// - create spaghetti code
+		grep				:1,	// - locate elements in a list test true against a given criterion
+		hex				:1,	// - convert a string to a hexadecimal number
+		'import'			:1,	// - patch a module's namespace into your own
+		index				:1,	// - find a substring within a string
+		'int'				:1,	// - get the integer portion of a number
+		ioctl				:1,	// - system-dependent device control system call
+		'join'				:1,	// - join a list into a string using a separator
+		keys				:1,	// - retrieve list of indices from a hash
+		kill				:1,	// - send a signal to a process or process group
+		last				:1,	// - exit a block prematurely
+		lc				:1,	// - return lower-case version of a string
+		lcfirst				:1,	// - return a string with just the next letter in lower case
+		length				:1,	// - return the number of bytes in a string
+		'link'				:1,	// - create a hard link in the filesytem
+		listen				:1,	// - register your socket as a server
+		local				: 2,	// - create a temporary value for a global variable (dynamic scoping)
+		localtime			:1,	// - convert UNIX time into record or string using local time
+		lock				:1,	// - get a thread lock on a variable, subroutine, or method
+		'log'				:1,	// - retrieve the natural logarithm for a number
+		lstat				:1,	// - stat a symbolic link
+		m				:null,	// - match a string with a regular expression pattern
+		map				:1,	// - apply a change to a list to get back a new list with the changes
+		mkdir				:1,	// - create a directory
+		msgctl				:1,	// - SysV IPC message control operations
+		msgget				:1,	// - get SysV IPC message queue
+		msgrcv				:1,	// - receive a SysV IPC message from a message queue
+		msgsnd				:1,	// - send a SysV IPC message to a message queue
+		my				: 2,	// - declare and assign a local variable (lexical scoping)
+		'new'				:1,	//
+		next				:1,	// - iterate a block prematurely
+		no				:1,	// - unimport some module symbols or semantics at compile time
+		oct				:1,	// - convert a string to an octal number
+		open				:1,	// - open a file, pipe, or descriptor
+		opendir				:1,	// - open a directory
+		ord				:1,	// - find a character's numeric representation
+		our				: 2,	// - declare and assign a package variable (lexical scoping)
+		pack				:1,	// - convert a list into a binary representation
+		'package'			:1,	// - declare a separate global namespace
+		pipe				:1,	// - open a pair of connected filehandles
+		pop				:1,	// - remove the last element from an array and return it
+		pos				:1,	// - find or set the offset for the last/next m//g search
+		print				:1,	// - output a list to a filehandle
+		printf				:1,	// - output a formatted list to a filehandle
+		prototype			:1,	// - get the prototype (if any) of a subroutine
+		push				:1,	// - append one or more elements to an array
+		q				:null,	// - singly quote a string
+		qq				:null,	// - doubly quote a string
+		qr				:null,	// - Compile pattern
+		quotemeta			:null,	// - quote regular expression magic characters
+		qw				:null,	// - quote a list of words
+		qx				:null,	// - backquote quote a string
+		rand				:1,	// - retrieve the next pseudorandom number
+		read				:1,	// - fixed-length buffered input from a filehandle
+		readdir				:1,	// - get a directory from a directory handle
+		readline			:1,	// - fetch a record from a file
+		readlink			:1,	// - determine where a symbolic link is pointing
+		readpipe			:1,	// - execute a system command and collect standard output
+		recv				:1,	// - receive a message over a Socket
+		redo				:1,	// - start this loop iteration over again
+		ref				:1,	// - find out the type of thing being referenced
+		rename				:1,	// - change a filename
+		require				:1,	// - load in external functions from a library at runtime
+		reset				:1,	// - clear all variables of a given name
+		'return'			:1,	// - get out of a function early
+		reverse				:1,	// - flip a string or a list
+		rewinddir			:1,	// - reset directory handle
+		rindex				:1,	// - right-to-left substring search
+		rmdir				:1,	// - remove a directory
+		s				:null,	// - replace a pattern with a string
+		say				:1,	// - print with newline
+		scalar				:1,	// - force a scalar context
+		seek				:1,	// - reposition file pointer for random-access I/O
+		seekdir				:1,	// - reposition directory pointer
+		select				:1,	// - reset default output or do I/O multiplexing
+		semctl				:1,	// - SysV semaphore control operations
+		semget				:1,	// - get set of SysV semaphores
+		semop				:1,	// - SysV semaphore operations
+		send				:1,	// - send a message over a socket
+		setgrent			:1,	// - prepare group file for use
+		sethostent			:1,	// - prepare hosts file for use
+		setnetent			:1,	// - prepare networks file for use
+		setpgrp				:1,	// - set the process group of a process
+		setpriority			:1,	// - set a process's nice value
+		setprotoent			:1,	// - prepare protocols file for use
+		setpwent			:1,	// - prepare passwd file for use
+		setservent			:1,	// - prepare services file for use
+		setsockopt			:1,	// - set some socket options
+		shift				:1,	// - remove the first element of an array, and return it
+		shmctl				:1,	// - SysV shared memory operations
+		shmget				:1,	// - get SysV shared memory segment identifier
+		shmread				:1,	// - read SysV shared memory
+		shmwrite			:1,	// - write SysV shared memory
+		shutdown			:1,	// - close down just half of a socket connection
+		'sin'				:1,	// - return the sine of a number
+		sleep				:1,	// - block for some number of seconds
+		socket				:1,	// - create a socket
+		socketpair			:1,	// - create a pair of sockets
+		'sort'				:1,	// - sort a list of values
+		splice				:1,	// - add or remove elements anywhere in an array
+		'split'				:1,	// - split up a string using a regexp delimiter
+		sprintf				:1,	// - formatted print into a string
+		'sqrt'				:1,	// - square root function
+		srand				:1,	// - seed the random number generator
+		stat				:1,	// - get a file's status information
+		state				:1,	// - declare and assign a state variable (persistent lexical scoping)
+		study				:1,	// - optimize input data for repeated searches
+		'sub'				:1,	// - declare a subroutine, possibly anonymously
+		'substr'			:1,	// - get or alter a portion of a stirng
+		symlink				:1,	// - create a symbolic link to a file
+		syscall				:1,	// - execute an arbitrary system call
+		sysopen				:1,	// - open a file, pipe, or descriptor
+		sysread				:1,	// - fixed-length unbuffered input from a filehandle
+		sysseek				:1,	// - position I/O pointer on handle used with sysread and syswrite
+		system				:1,	// - run a separate program
+		syswrite			:1,	// - fixed-length unbuffered output to a filehandle
+		tell				:1,	// - get current seekpointer on a filehandle
+		telldir				:1,	// - get current seekpointer on a directory handle
+		tie				:1,	// - bind a variable to an object class
+		tied				:1,	// - get a reference to the object underlying a tied variable
+		time				:1,	// - return number of seconds since 1970
+		times				:1,	// - return elapsed time for self and child processes
+		tr				:null,	// - transliterate a string
+		truncate			:1,	// - shorten a file
+		uc				:1,	// - return upper-case version of a string
+		ucfirst				:1,	// - return a string with just the next letter in upper case
+		umask				:1,	// - set file creation mode mask
+		undef				:1,	// - remove a variable or function definition
+		unlink				:1,	// - remove one link to a file
+		unpack				:1,	// - convert binary structure into normal perl variables
+		unshift				:1,	// - prepend more elements to the beginning of a list
+		untie				:1,	// - break a tie binding to a variable
+		use				:1,	// - load in a module at compile time
+		utime				:1,	// - set a file's last access and modify times
+		values				:1,	// - return a list of the values in a hash
+		vec				:1,	// - test or set particular bits in a string
+		wait				:1,	// - wait for any child process to die
+		waitpid				:1,	// - wait for a particular child process to die
+		wantarray			:1,	// - get void vs scalar vs list context of current subroutine call
+		warn				:1,	// - print debugging info
+		when				:1,	//
+		write				:1,	// - print a picture record
+		y				:null};	// - transliterate a string
+
+	var RXstyle="string-2";
+	var RXmodifiers=/[goseximacplud]/;		// NOTE: "m", "s", "y" and "tr" need to correct real modifiers for each regexp type
+
+	function tokenChain(stream,state,chain,style,tail){	// NOTE: chain.length > 2 is not working now (it's for s[...][...]geos;)
+		state.chain=null;                               //                                                          12   3tail
+		state.style=null;
+		state.tail=null;
+		state.tokenize=function(stream,state){
+			var e=false,c,i=0;
+			while(c=stream.next()){
+				if(c===chain[i]&&!e){
+					if(chain[++i]!==undefined){
+						state.chain=chain[i];
+						state.style=style;
+						state.tail=tail}
+					else if(tail)
+						stream.eatWhile(tail);
+					state.tokenize=tokenPerl;
+					return style}
+				e=!e&&c=="\\"}
+			return style};
+		return state.tokenize(stream,state)}
+
+	function tokenSOMETHING(stream,state,string){
+		state.tokenize=function(stream,state){
+			if(stream.string==string)
+				state.tokenize=tokenPerl;
+			stream.skipToEnd();
+			return "string"};
+		return state.tokenize(stream,state)}
+
+	function tokenPerl(stream,state){
+		if(stream.eatSpace())
+			return null;
+		if(state.chain)
+			return tokenChain(stream,state,state.chain,state.style,state.tail);
+		if(stream.match(/^\-?[\d\.]/,false))
+			if(stream.match(/^(\-?(\d*\.\d+(e[+-]?\d+)?|\d+\.\d*)|0x[\da-fA-F]+|0b[01]+|\d+(e[+-]?\d+)?)/))
+				return 'number';
+		if(stream.match(/^<<(?=\w)/)){			// NOTE: <<SOMETHING\n...\nSOMETHING\n
+			stream.eatWhile(/\w/);
+			return tokenSOMETHING(stream,state,stream.current().substr(2))}
+		if(stream.sol()&&stream.match(/^\=item(?!\w)/)){// NOTE: \n=item...\n=cut\n
+			return tokenSOMETHING(stream,state,'=cut')}
+		var ch=stream.next();
+		if(ch=='"'||ch=="'"){				// NOTE: ' or " or <<'SOMETHING'\n...\nSOMETHING\n or <<"SOMETHING"\n...\nSOMETHING\n
+			if(stream.prefix(3)=="<<"+ch){
+				var p=stream.pos;
+				stream.eatWhile(/\w/);
+				var n=stream.current().substr(1);
+				if(n&&stream.eat(ch))
+					return tokenSOMETHING(stream,state,n);
+				stream.pos=p}
+			return tokenChain(stream,state,[ch],"string")}
+		if(ch=="q"){
+			var c=stream.look(-2);
+			if(!(c&&/\w/.test(c))){
+				c=stream.look(0);
+				if(c=="x"){
+					c=stream.look(1);
+					if(c=="("){
+						stream.eatSuffix(2);
+						return tokenChain(stream,state,[")"],RXstyle,RXmodifiers)}
+					if(c=="["){
+						stream.eatSuffix(2);
+						return tokenChain(stream,state,["]"],RXstyle,RXmodifiers)}
+					if(c=="{"){
+						stream.eatSuffix(2);
+						return tokenChain(stream,state,["}"],RXstyle,RXmodifiers)}
+					if(c=="<"){
+						stream.eatSuffix(2);
+						return tokenChain(stream,state,[">"],RXstyle,RXmodifiers)}
+                                        if(c=="CASE"){
+						stream.eatSuffix(2);
+                                                return tokenChain(stream,state,["END CASE"],RXstyle,RXmodifiers)}
+					if(/[\^'"!~\/]/.test(c)){
+						stream.eatSuffix(1);
+						return tokenChain(stream,state,[stream.eat(c)],RXstyle,RXmodifiers)}}
+				else if(c=="q"){
+					c=stream.look(1);
+					if(c=="("){
+						stream.eatSuffix(2);
+						return tokenChain(stream,state,[")"],"string")}
+					if(c=="["){
+						stream.eatSuffix(2);
+						return tokenChain(stream,state,["]"],"string")}
+					if(c=="{"){
+						stream.eatSuffix(2);
+						return tokenChain(stream,state,["}"],"string")}
+					if(c=="<"){
+						stream.eatSuffix(2);
+						return tokenChain(stream,state,[">"],"string")}
+					if(/[\^'"!~\/]/.test(c)){
+						stream.eatSuffix(1);
+						return tokenChain(stream,state,[stream.eat(c)],"string")}}
+				else if(c=="w"){
+					c=stream.look(1);
+					if(c=="("){
+						stream.eatSuffix(2);
+						return tokenChain(stream,state,[")"],"bracket")}
+					if(c=="["){
+						stream.eatSuffix(2);
+						return tokenChain(stream,state,["]"],"bracket")}
+					if(c=="{"){
+						stream.eatSuffix(2);
+						return tokenChain(stream,state,["}"],"bracket")}
+                                        if(c=="CASE"){
+                                                stream.eatSuffix(2);
+                                                return tokenChain(stream,state,["END CASE"],"bracket")}
+					if(c=="<"){
+						stream.eatSuffix(2);
+						return tokenChain(stream,state,[">"],"bracket")}
+					if(/[\^'"!~\/]/.test(c)){
+						stream.eatSuffix(1);
+						return tokenChain(stream,state,[stream.eat(c)],"bracket")}}
+				else if(c=="r"){
+					c=stream.look(1);
+					if(c=="("){
+						stream.eatSuffix(2);
+						return tokenChain(stream,state,[")"],RXstyle,RXmodifiers)}
+					if(c=="["){
+						stream.eatSuffix(2);
+						return tokenChain(stream,state,["]"],RXstyle,RXmodifiers)}
+					if(c=="{"){
+						stream.eatSuffix(2);
+						return tokenChain(stream,state,["}"],RXstyle,RXmodifiers)}
+					if(c=="<"){
+						stream.eatSuffix(2);
+						return tokenChain(stream,state,[">"],RXstyle,RXmodifiers)}
+					if(/[\^'"!~\/]/.test(c)){
+						stream.eatSuffix(1);
+						return tokenChain(stream,state,[stream.eat(c)],RXstyle,RXmodifiers)}}
+				else if(/[\^'"!~\/(\[{<]/.test(c)){
+					if(c=="("){
+						stream.eatSuffix(1);
+						return tokenChain(stream,state,[")"],"string")}
+					if(c=="["){
+						stream.eatSuffix(1);
+						return tokenChain(stream,state,["]"],"string")}
+					if(c=="{"){
+						stream.eatSuffix(1);
+						return tokenChain(stream,state,["}"],"string")}
+					if(c=="<"){
+						stream.eatSuffix(1);
+						return tokenChain(stream,state,[">"],"string")}
+					if(/[\^'"!~\/]/.test(c)){
+						return tokenChain(stream,state,[stream.eat(c)],"string")}}}}
+		if(ch=="m"){
+			var c=stream.look(-2);
+			if(!(c&&/\w/.test(c))){
+				c=stream.eat(/[(\[{<\^'"!~\/]/);
+				if(c){
+					if(/[\^'"!~\/]/.test(c)){
+						return tokenChain(stream,state,[c],RXstyle,RXmodifiers)}
+					if(c=="("){
+						return tokenChain(stream,state,[")"],RXstyle,RXmodifiers)}
+					if(c=="["){
+						return tokenChain(stream,state,["]"],RXstyle,RXmodifiers)}
+					if(c=="{"){
+						return tokenChain(stream,state,["}"],RXstyle,RXmodifiers)}
+					if(c=="<"){
+						return tokenChain(stream,state,[">"],RXstyle,RXmodifiers)}}}}
+		if(ch=="s"){
+			var c=/[\/>\]})\w]/.test(stream.look(-2));
+			if(!c){
+				c=stream.eat(/[(\[{<\^'"!~\/]/);
+				if(c){
+					if(c=="[")
+						return tokenChain(stream,state,["]","]"],RXstyle,RXmodifiers);
+					if(c=="{")
+						return tokenChain(stream,state,["}","}"],RXstyle,RXmodifiers);
+					if(c=="<")
+						return tokenChain(stream,state,[">",">"],RXstyle,RXmodifiers);
+					if(c=="(")
+						return tokenChain(stream,state,[")",")"],RXstyle,RXmodifiers);
+					return tokenChain(stream,state,[c,c],RXstyle,RXmodifiers)}}}
+		if(ch=="y"){
+			var c=/[\/>\]})\w]/.test(stream.look(-2));
+			if(!c){
+				c=stream.eat(/[(\[{<\^'"!~\/]/);
+				if(c){
+					if(c=="[")
+						return tokenChain(stream,state,["]","]"],RXstyle,RXmodifiers);
+					if(c=="{")
+						return tokenChain(stream,state,["}","}"],RXstyle,RXmodifiers);
+					if(c=="<")
+						return tokenChain(stream,state,[">",">"],RXstyle,RXmodifiers);
+					if(c=="(")
+						return tokenChain(stream,state,[")",")"],RXstyle,RXmodifiers);
+					return tokenChain(stream,state,[c,c],RXstyle,RXmodifiers)}}}
+		if(ch=="t"){
+			var c=/[\/>\]})\w]/.test(stream.look(-2));
+			if(!c){
+				c=stream.eat("r");if(c){
+				c=stream.eat(/[(\[{<\^'"!~\/]/);
+				if(c){
+					if(c=="[")
+						return tokenChain(stream,state,["]","]"],RXstyle,RXmodifiers);
+					if(c=="{")
+						return tokenChain(stream,state,["}","}"],RXstyle,RXmodifiers);
+					if(c=="<")
+						return tokenChain(stream,state,[">",">"],RXstyle,RXmodifiers);
+					if(c=="(")
+						return tokenChain(stream,state,[")",")"],RXstyle,RXmodifiers);
+					return tokenChain(stream,state,[c,c],RXstyle,RXmodifiers)}}}}
+		if(ch=="`"){
+			return tokenChain(stream,state,[ch],"variable-2")}
+		if(ch=="/"){
+			if(!/~\s*$/.test(stream.prefix()))
+				return "operator";
+			else
+				return tokenChain(stream,state,[ch],RXstyle,RXmodifiers)}
+		if(ch=="$"){
+			var p=stream.pos;
+			if(stream.eatWhile(/\d/)||stream.eat("{")&&stream.eatWhile(/\d/)&&stream.eat("}"))
+				return "variable-2";
+			else
+				stream.pos=p}
+		if(/[$@%]/.test(ch)){
+			var p=stream.pos;
+			if(stream.eat("^")&&stream.eat(/[A-Z]/)||!/[@$%&]/.test(stream.look(-2))&&stream.eat(/[=|\\\-#?@;:&`~\^!\[\]*'"$+.,\/<>()]/)){
+				var c=stream.current();
+				if(PERL[c])
+					return "variable-2"}
+			stream.pos=p}
+		if(/[$@%&]/.test(ch)){
+			if(stream.eatWhile(/[\w$\[\]]/)||stream.eat("{")&&stream.eatWhile(/[\w$\[\]]/)&&stream.eat("}")){
+				var c=stream.current();
+				if(PERL[c])
+					return "variable-2";
+				else
+					return "variable"}}
+		
+
+
+if (ch == "S") {
+    if (stream.eat("T")) {
+        if (stream.eat("A")) {
+            if (stream.eat("R")) {
+                stream.skipToEnd();
+                return "log_start_end_case";
+            }             
+        } else if (stream.eat("E")) {
+            if (stream.eat("P")) { 
+               stream.skipToEnd();
+               return "log_step";
+            }
+        }
+    }
+}
+
+
+
+
+
+
+
+
+if (ch == "S") {
+    if (stream.eat("T")) {
+        if (stream.eat("E")) {
+          if (stream.eat("P")) {
+
+            stream.skipToEnd();
+            return "log_step";
+         }
+      }
+      }
+    }
+
+
+
+if (ch == "P" && stream.eat("A") && stream.eat("S") && stream.eat("S") && stream.eat("E") && stream.eat("D") ) {
+            return "log_pass";
+    }
+
+
+
+
+
+
+   if (ch == "I") {
+    if (stream.eat("N")) {
+        if (stream.eat("F")) {
+          if (stream.eat("O")) {
+
+            stream.skipToEnd();
+            return "log_info";
+         }
+      }
+      }
+    }
+
+
+
+
+
+
+
+
+    if (ch == "D") {
+        if (stream.eat("E")) {
+            if (stream.eat("S")) {
+                if (stream.eat("C")) {
+                   stream.skipToEnd();
+                   return "log_description";
+                }
+            } else if(stream.eat("B")) {
+                if(stream.eat("U")) {
+                    if(stream.eat("G")) {
+                        stream.skipToEnd();
+                        return "log_debug";
+                    }
+                }
+           }                   
+       }
+   }
+
+
+
+
+
+
+   if (ch == "-") {
+   
+      if (stream.eat("-")) {
+        if (stream.eat("-")) {
+          if (stream.eat(" ")) {
+     
+            stream.skipToEnd();
+            return "log_error_warn";
+         }
+      }
+      }
+    }
+
+
+
+
+
+  if (ch == "+") {
+     if (stream.eat("+")) {
+        if (stream.eat("+")) {
+          if (stream.eat(" ")) {
+
+            stream.skipToEnd();
+            return "log_pass";
+         }
+      }
+      }
+    }
+
+
+
+
+
+
+
+
+if (ch == "E") {
+   
+      if (stream.eat("N")) {
+        if (stream.eat("D")) {
+          if (stream.eat("C")) {
+           if (stream.eat("A")) {
+             if (stream.eat("S"))  {
+
+               stream.skipToEnd();
+               return "log_start_end_case";
+             }
+           }
+         }
+      }
+      }
+    }
+
+
+
+                        if(ch=="#"){
+			if(stream.look(-2)!="$"){
+				stream.skipToEnd();
+				return "comment"}}
+                 
+
+                
+
+
+
+		if(/[:+\-\^*$&%@=<>!?|\/~\.]/.test(ch)){
+			var p=stream.pos;
+			stream.eatWhile(/[:+\-\^*$&%@=<>!?|\/~\.]/);
+			if(PERL[stream.current()])
+				return "operator";
+			else
+				stream.pos=p}
+		if(ch=="_"){
+			if(stream.pos==1){
+				if(stream.suffix(6)=="_END__"){
+					return tokenChain(stream,state,['\0'],"comment")}
+				else if(stream.suffix(7)=="_DATA__"){
+					return tokenChain(stream,state,['\0'],"variable-2")}
+				else if(stream.suffix(7)=="_C__"){
+					return tokenChain(stream,state,['\0'],"string")}}}
+		if(/\w/.test(ch)){
+			var p=stream.pos;
+			if(stream.look(-2)=="{"&&(stream.look(0)=="}"||stream.eatWhile(/\w/)&&stream.look(0)=="}"))
+				return "string";
+			else
+				stream.pos=p}
+		if(/[A-Z]/.test(ch)){
+			var l=stream.look(-2);
+			var p=stream.pos;
+			stream.eatWhile(/[A-Z_]/);
+			if(/[\da-z]/.test(stream.look(0))){
+				stream.pos=p}
+			else{
+				var c=PERL[stream.current()];
+				if(!c)
+					return "meta";
+				if(c[1])
+					c=c[0];
+				if(l!=":"){
+					if(c==1)
+						return "keyword";
+					else if(c==2)
+						return "def";
+					else if(c==3)
+						return "atom";
+					else if(c==4)
+						return "operator";
+					else if(c==5)
+						return "variable-2";
+					else
+						return "meta"}
+				else
+					return "meta"}}
+
+
+
+		if(/[a-zA-Z_]/.test(ch)){
+			var l=stream.look(-2);
+			stream.eatWhile(/\w/);
+			var c=PERL[stream.current()];
+			if(!c)
+				return "meta";
+			if(c[1])
+				c=c[0];
+			if(l!=":"){
+				if(c==1)
+					return "keyword";
+				else if(c==2)
+					return "def";
+				else if(c==3)
+					return "atom";
+				else if(c==4)
+					return "operator";
+				else if(c==5)
+					return "variable-2";
+				else
+					return "meta"}
+			else
+				return "meta"}
+		return null }
+       
+
+	return{
+		startState:function(){
+			return{
+				tokenize:tokenPerl,
+				chain:null,
+				style:null,
+				tail:null}},
+		token:function(stream,state){
+			return (state.tokenize||tokenPerl)(stream,state)},
+		electricChars:"{}"}});
+
+CodeMirror.defineMIME("text/x-perl", "perl");
+
+// it's like "peek", but need for look-ahead or look-behind if index < 0
+CodeMirror.StringStream.prototype.look=function(c){
+	return this.string.charAt(this.pos+(c||0))};
+
+// return a part of prefix of current stream from current position
+CodeMirror.StringStream.prototype.prefix=function(c){
+	if(c){
+		var x=this.pos-c;
+		return this.string.substr((x>=0?x:0),c)}
+	else{
+		return this.string.substr(0,this.pos-1)}};
+
+// return a part of suffix of current stream from current position
+CodeMirror.StringStream.prototype.suffix=function(c){
+	var y=this.string.length;
+	var x=y-this.pos+1;
+	return this.string.substr(this.pos,(c&&c<y?c:x))};
+
+// return a part of suffix of current stream from current position and change current position
+CodeMirror.StringStream.prototype.nsuffix=function(c){
+	var p=this.pos;
+	var l=c||(this.string.length-this.pos+1);
+	this.pos+=l;
+	return this.string.substr(p,l)};
+
+// eating and vomiting a part of stream from current position
+CodeMirror.StringStream.prototype.eatSuffix=function(c){
+	var x=this.pos+c;
+	var y;
+	if(x<=0)
+		this.pos=0;
+	else if(x>=(y=this.string.length-1))
+		this.pos=y;
+	else
+		this.pos=x};
diff --git a/TestON/TAI/src/EditorScripts/save.png b/TestON/TAI/src/EditorScripts/save.png
new file mode 100644
index 0000000..ed3da6d
--- /dev/null
+++ b/TestON/TAI/src/EditorScripts/save.png
Binary files differ
diff --git a/TestON/TAI/src/EditorScripts/search.js b/TestON/TAI/src/EditorScripts/search.js
new file mode 100644
index 0000000..22e1c2d
--- /dev/null
+++ b/TestON/TAI/src/EditorScripts/search.js
@@ -0,0 +1,114 @@
+// Define search commands. Depends on dialog.js or another
+// implementation of the openDialog method.
+
+// Replace works a little oddly -- it will do the replace on the next
+// Ctrl-G (or whatever is bound to findNext) press. You prevent a
+// replace by making sure the match is no longer selected when hitting
+// Ctrl-G.
+
+(function() {
+  function SearchState() {
+    this.posFrom = this.posTo = this.query = null;
+    this.marked = [];
+  }
+  function getSearchState(cm) {
+    return cm._searchState || (cm._searchState = new SearchState());
+  }
+  function dialog(cm, text, shortText, f) {
+    if (cm.openDialog) cm.openDialog(text, f);
+    else f(prompt(shortText, ""));
+  }
+  function confirmDialog(cm, text, shortText, fs) {
+    if (cm.openConfirm) cm.openConfirm(text, fs);
+    else if (confirm(shortText)) fs[0]();
+  }
+  function parseQuery(query) {
+    var isRE = query.match(/^\/(.*)\/$/);
+    return isRE ? new RegExp(isRE[1]) : query;
+  }
+  var queryDialog =
+    'Search: <input type="text" style="width: 10em"> <input type="submit" name=b1 value="Find"> <span style="color: #888">(Use /re/ syntax for regexp search)</span>';
+  function doSearch(cm, rev) {
+    var state = getSearchState(cm);
+    if (state.query) return findNext(cm,rev);
+    dialog(cm, queryDialog, "Search for:", function(query) {
+      cm.operation(function() {
+        if (!query || state.query) return;
+        state.query = parseQuery(query);
+        if (cm.lineCount() < 200000) { // This is too expensive on big documents.
+        for (var cursor = cm.getSearchCursor(query); cursor.findNext();)
+           state.marked.push(cm.markText(cursor.from(), cursor.to(), "CodeMirror-searching"));
+        }
+        state.posFrom = state.posTo = cm.getCursor();
+        findNext(cm, rev);
+      });
+    });
+  }
+  function findNext(cm, rev) {cm.operation(function() {
+    var state = getSearchState(cm);
+    var cursor = cm.getSearchCursor(state.query, rev ? state.posFrom : state.posTo);
+    if (!cursor.find(rev)) {
+      cursor = cm.getSearchCursor(state.query, rev ? {line: cm.lineCount() - 1} : {line: 0, ch: 0});
+      if (!cursor.find(rev)) return;
+    }
+//    cm.setSelection(cursor.from(), cursor.to());
+    state.posFrom = cursor.from(); state.posTo = cursor.to();
+  })}
+  function clearSearch(cm) {cm.operation(function() {
+    var state = getSearchState(cm);
+    if (!state.query) return;
+    state.query = null;
+    for (var i = 0; i < state.marked.length; ++i) state.marked[i].clear();
+    state.marked.length = 0;
+  })}
+
+  var replaceQueryDialog =
+    'Replace: <input type="text" style="width: 10em"> <span style="color: #888">(Use /re/ syntax for regexp search)</span>';
+  var replacementQueryDialog = 'With: <input type="text" style="width: 10em">';
+  var doReplaceConfirm = "Replace? <button>Yes</button> <button>No</button> <button>Stop</button>";
+  function replace(cm, all) {
+    dialog(cm, replaceQueryDialog, "Replace:", function(query) {
+      if (!query) return;
+      query = parseQuery(query);
+      dialog(cm, replacementQueryDialog, "Replace with:", function(text) {
+        if (all) {
+          cm.compoundChange(function() { cm.operation(function() {
+            for (var cursor = cm.getSearchCursor(query); cursor.findNext();) {
+              if (typeof query != "string") {
+                var match = cm.getRange(cursor.from(), cursor.to()).match(query);
+                cursor.replace(text.replace(/\$(\d)/, function(w, i) {return match[i];}));
+              } else cursor.replace(text);
+            }
+          })});
+        } else {
+          clearSearch(cm);
+          var cursor = cm.getSearchCursor(query, cm.getCursor());
+          function advance() {
+            var start = cursor.from(), match;
+            if (!(match = cursor.findNext())) {
+              cursor = cm.getSearchCursor(query);
+              if (!(match = cursor.findNext()) ||
+                  (cursor.from().line == start.line && cursor.from().ch == start.ch)) return;
+            }
+            cm.setSelection(cursor.from(), cursor.to());
+            confirmDialog(cm, doReplaceConfirm, "Replace?",
+                          [function() {doReplace(match);}, advance]);
+          }
+          function doReplace(match) {
+            cursor.replace(typeof query == "string" ? text :
+                           text.replace(/\$(\d)/, function(w, i) {return match[i];}));
+            advance();
+          }
+          advance();
+        }
+      });
+    });
+  }
+
+  CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);};
+  CodeMirror.commands.findNext = doSearch;
+  CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);};
+  CodeMirror.commands.clearSearch = clearSearch;
+  CodeMirror.commands.replace = replace;
+  CodeMirror.commands.replaceAll = function(cm) {replace(cm, true);};
+})();
diff --git a/TestON/TAI/src/EditorScripts/searchcursor.js b/TestON/TAI/src/EditorScripts/searchcursor.js
new file mode 100644
index 0000000..ec3f73c
--- /dev/null
+++ b/TestON/TAI/src/EditorScripts/searchcursor.js
@@ -0,0 +1,117 @@
+(function(){
+  function SearchCursor(cm, query, pos, caseFold) {
+    this.atOccurrence = false; this.cm = cm;
+    if (caseFold == null && typeof query == "string") caseFold = false;
+
+    pos = pos ? cm.clipPos(pos) : {line: 0, ch: 0};
+    this.pos = {from: pos, to: pos};
+
+    // The matches method is filled in based on the type of query.
+    // It takes a position and a direction, and returns an object
+    // describing the next occurrence of the query, or null if no
+    // more matches were found.
+    if (typeof query != "string") // Regexp match
+      this.matches = function(reverse, pos) {
+        if (reverse) {
+          var line = cm.getLine(pos.line).slice(0, pos.ch), match = line.match(query), start = 0;
+          while (match) {
+            var ind = line.indexOf(match[0]);
+            start += ind;
+            line = line.slice(ind + 1);
+            var newmatch = line.match(query);
+            if (newmatch) match = newmatch;
+            else break;
+            start++;
+          }
+        }
+        else {
+          var line = cm.getLine(pos.line).slice(pos.ch), match = line.match(query),
+          start = match && pos.ch + line.indexOf(match[0]);
+        }
+        if (match)
+          return {from: {line: pos.line, ch: start},
+                  to: {line: pos.line, ch: start + match[0].length},
+                  match: match};
+      };
+    else { // String query
+      if (caseFold) query = query.toLowerCase();
+      var fold = caseFold ? function(str){return str.toLowerCase();} : function(str){return str;};
+      var target = query.split("\n");
+      // Different methods for single-line and multi-line queries
+      if (target.length == 1)
+        this.matches = function(reverse, pos) {
+          var line = fold(cm.getLine(pos.line)), len = query.length, match;
+          if (reverse ? (pos.ch >= len && (match = line.lastIndexOf(query, pos.ch - len)) != -1)
+              : (match = line.indexOf(query, pos.ch)) != -1)
+            return {from: {line: pos.line, ch: match},
+                    to: {line: pos.line, ch: match + len}};
+        };
+      else
+        this.matches = function(reverse, pos) {
+          var ln = pos.line, idx = (reverse ? target.length - 1 : 0), match = target[idx], line = fold(cm.getLine(ln));
+          var offsetA = (reverse ? line.indexOf(match) + match.length : line.lastIndexOf(match));
+          if (reverse ? offsetA >= pos.ch || offsetA != match.length
+              : offsetA <= pos.ch || offsetA != line.length - match.length)
+            return;
+          for (;;) {
+            if (reverse ? !ln : ln == cm.lineCount() - 1) return;
+            line = fold(cm.getLine(ln += reverse ? -1 : 1));
+            match = target[reverse ? --idx : ++idx];
+            if (idx > 0 && idx < target.length - 1) {
+              if (line != match) return;
+              else continue;
+            }
+            var offsetB = (reverse ? line.lastIndexOf(match) : line.indexOf(match) + match.length);
+            if (reverse ? offsetB != line.length - match.length : offsetB != match.length)
+              return;
+            var start = {line: pos.line, ch: offsetA}, end = {line: ln, ch: offsetB};
+            return {from: reverse ? end : start, to: reverse ? start : end};
+          }
+        };
+    }
+  }
+
+  SearchCursor.prototype = {
+    findNext: function() {return this.find(false);},
+    findPrevious: function() {return this.find(true);},
+
+    find: function(reverse) {
+      var self = this, pos = this.cm.clipPos(reverse ? this.pos.from : this.pos.to);
+      function savePosAndFail(line) {
+        var pos = {line: line, ch: 0};
+        self.pos = {from: pos, to: pos};
+        self.atOccurrence = false;
+        return false;
+      }
+
+      for (;;) {
+        if (this.pos = this.matches(reverse, pos)) {
+          this.atOccurrence = true;
+          return this.pos.match || true;
+        }
+        if (reverse) {
+          if (!pos.line) return savePosAndFail(0);
+          pos = {line: pos.line-1, ch: this.cm.getLine(pos.line-1).length};
+        }
+        else {
+          var maxLine = this.cm.lineCount();
+          if (pos.line == maxLine - 1) return savePosAndFail(maxLine);
+          pos = {line: pos.line+1, ch: 0};
+        }
+      }
+    },
+
+    from: function() {if (this.atOccurrence) return this.pos.from;},
+    to: function() {if (this.atOccurrence) return this.pos.to;},
+
+    replace: function(newText) {
+      var self = this;
+      if (this.atOccurrence)
+        self.pos.to = this.cm.replaceRange(newText, self.pos.from, self.pos.to);
+    }
+  };
+
+  CodeMirror.defineExtension("getSearchCursor", function(query, pos, caseFold) {
+    return new SearchCursor(this, query, pos, caseFold);
+  });
+})();
diff --git a/TestON/TAI/src/EditorScripts/simple-hint.css b/TestON/TAI/src/EditorScripts/simple-hint.css
new file mode 100644
index 0000000..7bc8689
--- /dev/null
+++ b/TestON/TAI/src/EditorScripts/simple-hint.css
@@ -0,0 +1,17 @@
+.CodeMirror-completions {
+  position: absolute;
+  z-index: 10;
+  overflow: hidden;
+  -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
+  -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
+  box-shadow: 2px 3px 5px rgba(0,0,0,.2);
+}
+.CodeMirror-completions select {
+  background: #fafafa;
+  outline: none;
+  border: none;
+  padding: 0;
+  margin: 0;
+  font-family: monospace;
+}
+
diff --git a/TestON/TAI/src/EditorScripts/simple-hint.js b/TestON/TAI/src/EditorScripts/simple-hint.js
new file mode 100644
index 0000000..3e760fc
--- /dev/null
+++ b/TestON/TAI/src/EditorScripts/simple-hint.js
@@ -0,0 +1,73 @@
+(function() {
+  CodeMirror.simpleHint = function(editor, getHints) {
+    // We want a single cursor position.
+    if (editor.somethingSelected()) return;
+    var result = getHints(editor);
+    if (!result || !result.list.length) return;
+    var completions = result.list;
+    function insert(str) {
+      editor.replaceRange(str, result.from, result.to);
+    }
+    // When there is only one completion, use it directly.
+    if (completions.length == 1) {insert(completions[0]); return true;}
+
+    // Build the select widget
+    var complete = document.createElement("div");
+    complete.className = "CodeMirror-completions";
+    var sel = complete.appendChild(document.createElement("select"));
+    // Opera doesn't move the selection when pressing up/down in a
+    // multi-select, but it does properly support the size property on
+    // single-selects, so no multi-select is necessary.
+    if (!window.opera) sel.multiple = true;
+    for (var i = 0; i < completions.length; ++i) {
+      var opt = sel.appendChild(document.createElement("option"));
+      opt.appendChild(document.createTextNode(completions[i]));
+    }
+    sel.firstChild.selected = true;
+    sel.size = Math.min(10, completions.length);
+    var pos = editor.cursorCoords();
+    complete.style.left = pos.x + "px";
+    complete.style.top = pos.yBot + "px";
+    document.body.appendChild(complete);
+    // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
+    var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth);
+    if(winW - pos.x < sel.clientWidth)
+      complete.style.left = (pos.x - sel.clientWidth) + "px";
+    // Hack to hide the scrollbar.
+    if (completions.length <= 10)
+      complete.style.width = (sel.clientWidth - 1) + "px";
+
+    var done = false;
+    function close() {
+      if (done) return;
+      done = true;
+      complete.parentNode.removeChild(complete);
+    }
+    function pick() {
+      insert(completions[sel.selectedIndex]);
+      close();
+      setTimeout(function(){editor.focus();}, 50);
+    }
+    CodeMirror.connect(sel, "blur", close);
+    CodeMirror.connect(sel, "keydown", function(event) {
+      var code = event.keyCode;
+      // Enter
+      if (code == 13) {CodeMirror.e_stop(event); pick();}
+      // Escape
+      else if (code == 27) {CodeMirror.e_stop(event); close(); editor.focus();}
+      else if (code != 38 && code != 40) {
+        close(); editor.focus();
+        // Pass the event to the CodeMirror instance so that it can handle things like backspace properly.
+        editor.triggerOnKeyDown(event);
+        setTimeout(function(){CodeMirror.simpleHint(editor, getHints);}, 50);
+      }
+    });
+    CodeMirror.connect(sel, "dblclick", pick);
+
+    sel.focus();
+    // Opera sometimes ignores focusing a freshly created node
+    if (window.opera) setTimeout(function(){if (!done) sel.focus();}, 100);
+    return true;
+  };
+})();
+
diff --git a/TestON/TAI/src/EditorScripts/xml.js b/TestON/TAI/src/EditorScripts/xml.js
new file mode 100644
index 0000000..3fbe98f
--- /dev/null
+++ b/TestON/TAI/src/EditorScripts/xml.js
@@ -0,0 +1,325 @@
+CodeMirror.defineMode("xml", function(config, parserConfig) {
+  var indentUnit = config.indentUnit;
+  var Kludges = parserConfig.htmlMode ? {
+    autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
+                      'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
+                      'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
+                      'track': true, 'wbr': true},
+    implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
+                       'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
+                       'th': true, 'tr': true},
+    contextGrabbers: {
+      'dd': {'dd': true, 'dt': true},
+      'dt': {'dd': true, 'dt': true},
+      'li': {'li': true},
+      'option': {'option': true, 'optgroup': true},
+      'optgroup': {'optgroup': true},
+      'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
+            'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
+            'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
+            'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
+            'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
+      'rp': {'rp': true, 'rt': true},
+      'rt': {'rp': true, 'rt': true},
+      'tbody': {'tbody': true, 'tfoot': true},
+      'td': {'td': true, 'th': true},
+      'tfoot': {'tbody': true},
+      'th': {'td': true, 'th': true},
+      'thead': {'tbody': true, 'tfoot': true},
+      'tr': {'tr': true}
+    },
+    doNotIndent: {"pre": true},
+    allowUnquoted: true,
+    allowMissing: false
+  } : {
+    autoSelfClosers: {},
+    implicitlyClosed: {},
+    contextGrabbers: {},
+    doNotIndent: {},
+    allowUnquoted: false,
+    allowMissing: false
+  };
+  var alignCDATA = parserConfig.alignCDATA;
+
+  // Return variables for tokenizers
+  var tagName, type;
+
+  function inText(stream, state) {
+    function chain(parser) {
+      state.tokenize = parser;
+      return parser(stream, state);
+    }
+
+    var ch = stream.next();
+    if (ch == "<") {
+      if (stream.eat("!")) {
+        if (stream.eat("[")) {
+          if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
+          else return null;
+        }
+        else if (stream.match("--")) return chain(inBlock("comment", "-->"));
+        else if (stream.match("DOCTYPE", true, true)) {
+          stream.eatWhile(/[\w\._\-]/);
+          return chain(doctype(1));
+        }
+        else return null;
+      }
+      else if (stream.eat("?")) {
+        stream.eatWhile(/[\w\._\-]/);
+        state.tokenize = inBlock("meta", "?>");
+        return "meta";
+      }
+      else {
+        type = stream.eat("/") ? "closeTag" : "openTag";
+        stream.eatSpace();
+        tagName = "";
+        var c;
+        while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c;
+        state.tokenize = inTag;
+        return "tag";
+      }
+    }
+    else if (ch == "&") {
+      var ok;
+      if (stream.eat("#")) {
+        if (stream.eat("x")) {
+          ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");          
+        } else {
+          ok = stream.eatWhile(/[\d]/) && stream.eat(";");
+        }
+      } else {
+        ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
+      }
+      return ok ? "atom" : "error";
+    }
+    else {
+      stream.eatWhile(/[^&<]/);
+      return null;
+    }
+  }
+
+  function inTag(stream, state) {
+    var ch = stream.next();
+    if (ch == ">" || (ch == "/" && stream.eat(">"))) {
+      state.tokenize = inText;
+      type = ch == ">" ? "endTag" : "selfcloseTag";
+      return "tag";
+    }
+    else if (ch == "=") {
+      type = "equals";
+      return null;
+    }
+    else if (/[\'\"]/.test(ch)) {
+      state.tokenize = inAttribute(ch);
+      return state.tokenize(stream, state);
+    }
+    else {
+      stream.eatWhile(/[^\s\u00a0=<>\"\'\/?]/);
+      return "word";
+    }
+  }
+
+  function inAttribute(quote) {
+    return function(stream, state) {
+      while (!stream.eol()) {
+        if (stream.next() == quote) {
+          state.tokenize = inTag;
+          break;
+        }
+      }
+      return "string";
+    };
+  }
+
+  function inBlock(style, terminator) {
+    return function(stream, state) {
+      while (!stream.eol()) {
+        if (stream.match(terminator)) {
+          state.tokenize = inText;
+          break;
+        }
+        stream.next();
+      }
+      return style;
+    };
+  }
+  function doctype(depth) {
+    return function(stream, state) {
+      var ch;
+      while ((ch = stream.next()) != null) {
+        if (ch == "<") {
+          state.tokenize = doctype(depth + 1);
+          return state.tokenize(stream, state);
+        } else if (ch == ">") {
+          if (depth == 1) {
+            state.tokenize = inText;
+            break;
+          } else {
+            state.tokenize = doctype(depth - 1);
+            return state.tokenize(stream, state);
+          }
+        }
+      }
+      return "meta";
+    };
+  }
+
+  var curState, setStyle;
+  function pass() {
+    for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]);
+  }
+  function cont() {
+    pass.apply(null, arguments);
+    return true;
+  }
+
+  function pushContext(tagName, startOfLine) {
+    var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName) || (curState.context && curState.context.noIndent);
+    curState.context = {
+      prev: curState.context,
+      tagName: tagName,
+      indent: curState.indented,
+      startOfLine: startOfLine,
+      noIndent: noIndent
+    };
+  }
+  function popContext() {
+    if (curState.context) curState.context = curState.context.prev;
+  }
+
+  function element(type) {
+    if (type == "openTag") {
+      curState.tagName = tagName;
+      return cont(attributes, endtag(curState.startOfLine));
+    } else if (type == "closeTag") {
+      var err = false;
+      if (curState.context) {
+        if (curState.context.tagName != tagName) {
+          if (Kludges.implicitlyClosed.hasOwnProperty(curState.context.tagName.toLowerCase())) {
+            popContext();
+          }
+          err = !curState.context || curState.context.tagName != tagName;
+        }
+      } else {
+        err = true;
+      }
+      if (err) setStyle = "error";
+      return cont(endclosetag(err));
+    }
+    return cont();
+  }
+  function endtag(startOfLine) {
+    return function(type) {
+      if (type == "selfcloseTag" ||
+          (type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(curState.tagName.toLowerCase()))) {
+        maybePopContext(curState.tagName.toLowerCase());
+        return cont();
+      }
+      if (type == "endTag") {
+        maybePopContext(curState.tagName.toLowerCase());
+        pushContext(curState.tagName, startOfLine);
+        return cont();
+      }
+      return cont();
+    };
+  }
+  function endclosetag(err) {
+    return function(type) {
+      if (err) setStyle = "error";
+      if (type == "endTag") { popContext(); return cont(); }
+      setStyle = "error";
+      return cont(arguments.callee);
+    }
+  }
+  function maybePopContext(nextTagName) {
+    var parentTagName;
+    while (true) {
+      if (!curState.context) {
+        return;
+      }
+      parentTagName = curState.context.tagName.toLowerCase();
+      if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) ||
+          !Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
+        return;
+      }
+      popContext();
+    }
+  }
+
+  function attributes(type) {
+    if (type == "word") {setStyle = "attribute"; return cont(attribute, attributes);}
+    if (type == "endTag" || type == "selfcloseTag") return pass();
+    setStyle = "error";
+    return cont(attributes);
+  }
+  function attribute(type) {
+    if (type == "equals") return cont(attvalue, attributes);
+    if (!Kludges.allowMissing) setStyle = "error";
+    return (type == "endTag" || type == "selfcloseTag") ? pass() : cont();
+  }
+  function attvalue(type) {
+    if (type == "string") return cont(attvaluemaybe);
+    if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return cont();}
+    setStyle = "error";
+    return (type == "endTag" || type == "selfCloseTag") ? pass() : cont();
+  }
+  function attvaluemaybe(type) {
+    if (type == "string") return cont(attvaluemaybe);
+    else return pass();
+  }
+
+  return {
+    startState: function() {
+      return {tokenize: inText, cc: [], indented: 0, startOfLine: true, tagName: null, context: null};
+    },
+
+    token: function(stream, state) {
+      if (stream.sol()) {
+        state.startOfLine = true;
+        state.indented = stream.indentation();
+      }
+      if (stream.eatSpace()) return null;
+
+      setStyle = type = tagName = null;
+      var style = state.tokenize(stream, state);
+      state.type = type;
+      if ((style || type) && style != "comment") {
+        curState = state;
+        while (true) {
+          var comb = state.cc.pop() || element;
+          if (comb(type || style)) break;
+        }
+      }
+      state.startOfLine = false;
+      return setStyle || style;
+    },
+
+    indent: function(state, textAfter, fullLine) {
+      var context = state.context;
+      if ((state.tokenize != inTag && state.tokenize != inText) ||
+          context && context.noIndent)
+        return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
+      if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
+      if (context && /^<\//.test(textAfter))
+        context = context.prev;
+      while (context && !context.startOfLine)
+        context = context.prev;
+      if (context) return context.indent + indentUnit;
+      else return 0;
+    },
+
+    compareStates: function(a, b) {
+      if (a.indented != b.indented || a.tokenize != b.tokenize) return false;
+      for (var ca = a.context, cb = b.context; ; ca = ca.prev, cb = cb.prev) {
+        if (!ca || !cb) return ca == cb;
+        if (ca.tagName != cb.tagName) return false;
+      }
+    },
+
+    electricChars: "/"
+  };
+});
+
+CodeMirror.defineMIME("application/xml", "xml");
+if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
+  CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
diff --git a/TestON/TAI/src/images/Abort_Icon.png b/TestON/TAI/src/images/Abort_Icon.png
new file mode 100644
index 0000000..f00a170
--- /dev/null
+++ b/TestON/TAI/src/images/Abort_Icon.png
Binary files differ
diff --git a/TestON/TAI/src/images/AutoMate.jpg b/TestON/TAI/src/images/AutoMate.jpg
new file mode 100644
index 0000000..193601a
--- /dev/null
+++ b/TestON/TAI/src/images/AutoMate.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/AutoMate_Final.jpg b/TestON/TAI/src/images/AutoMate_Final.jpg
new file mode 100644
index 0000000..de4eadf
--- /dev/null
+++ b/TestON/TAI/src/images/AutoMate_Final.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/BDT.jpg b/TestON/TAI/src/images/BDT.jpg
new file mode 100644
index 0000000..34b04a1
--- /dev/null
+++ b/TestON/TAI/src/images/BDT.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/Cisco.png b/TestON/TAI/src/images/Cisco.png
new file mode 100644
index 0000000..f6b12a2
--- /dev/null
+++ b/TestON/TAI/src/images/Cisco.png
Binary files differ
diff --git a/TestON/TAI/src/images/Copy.png b/TestON/TAI/src/images/Copy.png
new file mode 100644
index 0000000..5802e5e
--- /dev/null
+++ b/TestON/TAI/src/images/Copy.png
Binary files differ
diff --git a/TestON/TAI/src/images/Fail_Icon.png b/TestON/TAI/src/images/Fail_Icon.png
new file mode 100644
index 0000000..cd86fed
--- /dev/null
+++ b/TestON/TAI/src/images/Fail_Icon.png
Binary files differ
diff --git a/TestON/TAI/src/images/File.png b/TestON/TAI/src/images/File.png
new file mode 100644
index 0000000..cce9db4
--- /dev/null
+++ b/TestON/TAI/src/images/File.png
Binary files differ
diff --git a/TestON/TAI/src/images/Link.png b/TestON/TAI/src/images/Link.png
new file mode 100644
index 0000000..d47e59e
--- /dev/null
+++ b/TestON/TAI/src/images/Link.png
Binary files differ
diff --git a/TestON/TAI/src/images/Link1.png b/TestON/TAI/src/images/Link1.png
new file mode 100644
index 0000000..227524d
--- /dev/null
+++ b/TestON/TAI/src/images/Link1.png
Binary files differ
diff --git a/TestON/TAI/src/images/New123.png b/TestON/TAI/src/images/New123.png
new file mode 100644
index 0000000..5fa9d36
--- /dev/null
+++ b/TestON/TAI/src/images/New123.png
Binary files differ
diff --git a/TestON/TAI/src/images/Pass_Icon.png b/TestON/TAI/src/images/Pass_Icon.png
new file mode 100644
index 0000000..7a45b06
--- /dev/null
+++ b/TestON/TAI/src/images/Pass_Icon.png
Binary files differ
diff --git a/TestON/TAI/src/images/Paste.jpg b/TestON/TAI/src/images/Paste.jpg
new file mode 100644
index 0000000..6f3d4fb
--- /dev/null
+++ b/TestON/TAI/src/images/Paste.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/Pause.jpg b/TestON/TAI/src/images/Pause.jpg
new file mode 100644
index 0000000..80621ea
--- /dev/null
+++ b/TestON/TAI/src/images/Pause.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/Pause.png b/TestON/TAI/src/images/Pause.png
new file mode 100644
index 0000000..efaa6c9
--- /dev/null
+++ b/TestON/TAI/src/images/Pause.png
Binary files differ
diff --git a/TestON/TAI/src/images/PauseDisabled.png b/TestON/TAI/src/images/PauseDisabled.png
new file mode 100644
index 0000000..1e34c86
--- /dev/null
+++ b/TestON/TAI/src/images/PauseDisabled.png
Binary files differ
diff --git a/TestON/TAI/src/images/Play1Normal.png b/TestON/TAI/src/images/Play1Normal.png
new file mode 100644
index 0000000..cf99faf
--- /dev/null
+++ b/TestON/TAI/src/images/Play1Normal.png
Binary files differ
diff --git a/TestON/TAI/src/images/Play1Pressed.png b/TestON/TAI/src/images/Play1Pressed.png
new file mode 100644
index 0000000..4aada73
--- /dev/null
+++ b/TestON/TAI/src/images/Play1Pressed.png
Binary files differ
diff --git a/TestON/TAI/src/images/Play_1.png b/TestON/TAI/src/images/Play_1.png
new file mode 100644
index 0000000..8177744
--- /dev/null
+++ b/TestON/TAI/src/images/Play_1.png
Binary files differ
diff --git a/TestON/TAI/src/images/Play_2.png b/TestON/TAI/src/images/Play_2.png
new file mode 100644
index 0000000..e67c135
--- /dev/null
+++ b/TestON/TAI/src/images/Play_2.png
Binary files differ
diff --git a/TestON/TAI/src/images/Refresh.png b/TestON/TAI/src/images/Refresh.png
new file mode 100644
index 0000000..16637ee
--- /dev/null
+++ b/TestON/TAI/src/images/Refresh.png
Binary files differ
diff --git a/TestON/TAI/src/images/Resume.png b/TestON/TAI/src/images/Resume.png
new file mode 100644
index 0000000..3d4557b
--- /dev/null
+++ b/TestON/TAI/src/images/Resume.png
Binary files differ
diff --git a/TestON/TAI/src/images/Resume_1.png b/TestON/TAI/src/images/Resume_1.png
new file mode 100644
index 0000000..98a2f1b
--- /dev/null
+++ b/TestON/TAI/src/images/Resume_1.png
Binary files differ
diff --git a/TestON/TAI/src/images/Save_24x24.png b/TestON/TAI/src/images/Save_24x24.png
new file mode 100644
index 0000000..919f2ef
--- /dev/null
+++ b/TestON/TAI/src/images/Save_24x24.png
Binary files differ
diff --git a/TestON/TAI/src/images/Settings.jpg b/TestON/TAI/src/images/Settings.jpg
new file mode 100644
index 0000000..f33a97c
--- /dev/null
+++ b/TestON/TAI/src/images/Settings.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/SlantLineLeft.jpg b/TestON/TAI/src/images/SlantLineLeft.jpg
new file mode 100644
index 0000000..3ab3a71
--- /dev/null
+++ b/TestON/TAI/src/images/SlantLineLeft.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/SlantLineRight.jpg b/TestON/TAI/src/images/SlantLineRight.jpg
new file mode 100644
index 0000000..47846ab
--- /dev/null
+++ b/TestON/TAI/src/images/SlantLineRight.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/Stop.png b/TestON/TAI/src/images/Stop.png
new file mode 100644
index 0000000..6bdf7da
--- /dev/null
+++ b/TestON/TAI/src/images/Stop.png
Binary files differ
diff --git a/TestON/TAI/src/images/TestON.png b/TestON/TAI/src/images/TestON.png
new file mode 100644
index 0000000..055b6ec
--- /dev/null
+++ b/TestON/TAI/src/images/TestON.png
Binary files differ
diff --git a/TestON/TAI/src/images/Thumbs.db b/TestON/TAI/src/images/Thumbs.db
new file mode 100644
index 0000000..dd98e8e
--- /dev/null
+++ b/TestON/TAI/src/images/Thumbs.db
Binary files differ
diff --git a/TestON/TAI/src/images/abort.png b/TestON/TAI/src/images/abort.png
new file mode 100644
index 0000000..b6087f7
--- /dev/null
+++ b/TestON/TAI/src/images/abort.png
Binary files differ
diff --git a/TestON/TAI/src/images/add.png b/TestON/TAI/src/images/add.png
new file mode 100644
index 0000000..6720740
--- /dev/null
+++ b/TestON/TAI/src/images/add.png
Binary files differ
diff --git a/TestON/TAI/src/images/amex.png b/TestON/TAI/src/images/amex.png
new file mode 100644
index 0000000..63bd2a3
--- /dev/null
+++ b/TestON/TAI/src/images/amex.png
Binary files differ
diff --git a/TestON/TAI/src/images/api.jpg b/TestON/TAI/src/images/api.jpg
new file mode 100644
index 0000000..33d7930
--- /dev/null
+++ b/TestON/TAI/src/images/api.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/automatorui.png b/TestON/TAI/src/images/automatorui.png
new file mode 100644
index 0000000..a31ed99
--- /dev/null
+++ b/TestON/TAI/src/images/automatorui.png
Binary files differ
diff --git a/TestON/TAI/src/images/bdt.png b/TestON/TAI/src/images/bdt.png
new file mode 100644
index 0000000..b4587cd
--- /dev/null
+++ b/TestON/TAI/src/images/bdt.png
Binary files differ
diff --git a/TestON/TAI/src/images/bold.png b/TestON/TAI/src/images/bold.png
new file mode 100644
index 0000000..889ae80
--- /dev/null
+++ b/TestON/TAI/src/images/bold.png
Binary files differ
diff --git a/TestON/TAI/src/images/calendar.jpg b/TestON/TAI/src/images/calendar.jpg
new file mode 100644
index 0000000..158d4a6
--- /dev/null
+++ b/TestON/TAI/src/images/calendar.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/child.jpg b/TestON/TAI/src/images/child.jpg
new file mode 100644
index 0000000..f39261f
--- /dev/null
+++ b/TestON/TAI/src/images/child.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/clipboard.png b/TestON/TAI/src/images/clipboard.png
new file mode 100644
index 0000000..084debf
--- /dev/null
+++ b/TestON/TAI/src/images/clipboard.png
Binary files differ
diff --git a/TestON/TAI/src/images/close_icon.jpg b/TestON/TAI/src/images/close_icon.jpg
new file mode 100644
index 0000000..73a787b
--- /dev/null
+++ b/TestON/TAI/src/images/close_icon.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/close_icon2.jpg b/TestON/TAI/src/images/close_icon2.jpg
new file mode 100644
index 0000000..64257f0
--- /dev/null
+++ b/TestON/TAI/src/images/close_icon2.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/compile.jpg b/TestON/TAI/src/images/compile.jpg
new file mode 100644
index 0000000..8a2f63f
--- /dev/null
+++ b/TestON/TAI/src/images/compile.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/controller.jpg b/TestON/TAI/src/images/controller.jpg
new file mode 100644
index 0000000..82ee451
--- /dev/null
+++ b/TestON/TAI/src/images/controller.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/currentcase.jpg b/TestON/TAI/src/images/currentcase.jpg
new file mode 100644
index 0000000..13f2263
--- /dev/null
+++ b/TestON/TAI/src/images/currentcase.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/currentstep.png b/TestON/TAI/src/images/currentstep.png
new file mode 100644
index 0000000..cb90996
--- /dev/null
+++ b/TestON/TAI/src/images/currentstep.png
Binary files differ
diff --git a/TestON/TAI/src/images/customerDetails.png b/TestON/TAI/src/images/customerDetails.png
new file mode 100644
index 0000000..16fdff2
--- /dev/null
+++ b/TestON/TAI/src/images/customerDetails.png
Binary files differ
diff --git a/TestON/TAI/src/images/cut.png b/TestON/TAI/src/images/cut.png
new file mode 100644
index 0000000..6895266
--- /dev/null
+++ b/TestON/TAI/src/images/cut.png
Binary files differ
diff --git a/TestON/TAI/src/images/decreaseFont.png b/TestON/TAI/src/images/decreaseFont.png
new file mode 100644
index 0000000..d1a33eb
--- /dev/null
+++ b/TestON/TAI/src/images/decreaseFont.png
Binary files differ
diff --git a/TestON/TAI/src/images/defaultTerminal.png b/TestON/TAI/src/images/defaultTerminal.png
new file mode 100644
index 0000000..fe8813b
--- /dev/null
+++ b/TestON/TAI/src/images/defaultTerminal.png
Binary files differ
diff --git a/TestON/TAI/src/images/delete.png b/TestON/TAI/src/images/delete.png
new file mode 100644
index 0000000..b36411e
--- /dev/null
+++ b/TestON/TAI/src/images/delete.png
Binary files differ
diff --git a/TestON/TAI/src/images/discover.png b/TestON/TAI/src/images/discover.png
new file mode 100644
index 0000000..ac3f1c4
--- /dev/null
+++ b/TestON/TAI/src/images/discover.png
Binary files differ
diff --git a/TestON/TAI/src/images/do.jpg b/TestON/TAI/src/images/do.jpg
new file mode 100644
index 0000000..8ac6f74
--- /dev/null
+++ b/TestON/TAI/src/images/do.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/dpctl.jpg b/TestON/TAI/src/images/dpctl.jpg
new file mode 100644
index 0000000..0831033
--- /dev/null
+++ b/TestON/TAI/src/images/dpctl.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/dumpvar.png b/TestON/TAI/src/images/dumpvar.png
new file mode 100644
index 0000000..b16a364
--- /dev/null
+++ b/TestON/TAI/src/images/dumpvar.png
Binary files differ
diff --git a/TestON/TAI/src/images/edit.png b/TestON/TAI/src/images/edit.png
new file mode 100644
index 0000000..a25865b
--- /dev/null
+++ b/TestON/TAI/src/images/edit.png
Binary files differ
diff --git a/TestON/TAI/src/images/email.png b/TestON/TAI/src/images/email.png
new file mode 100644
index 0000000..2b9d514
--- /dev/null
+++ b/TestON/TAI/src/images/email.png
Binary files differ
diff --git a/TestON/TAI/src/images/emulator.jpg b/TestON/TAI/src/images/emulator.jpg
new file mode 100644
index 0000000..e899e67
--- /dev/null
+++ b/TestON/TAI/src/images/emulator.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/eraser.png b/TestON/TAI/src/images/eraser.png
new file mode 100644
index 0000000..1e29046
--- /dev/null
+++ b/TestON/TAI/src/images/eraser.png
Binary files differ
diff --git a/TestON/TAI/src/images/exit.gif b/TestON/TAI/src/images/exit.gif
new file mode 100644
index 0000000..8afc793
--- /dev/null
+++ b/TestON/TAI/src/images/exit.gif
Binary files differ
diff --git a/TestON/TAI/src/images/exit.png b/TestON/TAI/src/images/exit.png
new file mode 100644
index 0000000..c9fb752
--- /dev/null
+++ b/TestON/TAI/src/images/exit.png
Binary files differ
diff --git a/TestON/TAI/src/images/fail.png b/TestON/TAI/src/images/fail.png
new file mode 100644
index 0000000..763bbd5
--- /dev/null
+++ b/TestON/TAI/src/images/fail.png
Binary files differ
diff --git a/TestON/TAI/src/images/floodlight.jpg b/TestON/TAI/src/images/floodlight.jpg
new file mode 100644
index 0000000..074f5a9
--- /dev/null
+++ b/TestON/TAI/src/images/floodlight.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/flowvisor.png b/TestON/TAI/src/images/flowvisor.png
new file mode 100644
index 0000000..8b234cc
--- /dev/null
+++ b/TestON/TAI/src/images/flowvisor.png
Binary files differ
diff --git a/TestON/TAI/src/images/folder.jpg b/TestON/TAI/src/images/folder.jpg
new file mode 100644
index 0000000..c9e6195
--- /dev/null
+++ b/TestON/TAI/src/images/folder.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/ftp.jpg b/TestON/TAI/src/images/ftp.jpg
new file mode 100644
index 0000000..30fbcb9
--- /dev/null
+++ b/TestON/TAI/src/images/ftp.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/giftWrap.png b/TestON/TAI/src/images/giftWrap.png
new file mode 100644
index 0000000..5344a1c
--- /dev/null
+++ b/TestON/TAI/src/images/giftWrap.png
Binary files differ
diff --git a/TestON/TAI/src/images/gmail.png b/TestON/TAI/src/images/gmail.png
new file mode 100644
index 0000000..fbdc7e0
--- /dev/null
+++ b/TestON/TAI/src/images/gmail.png
Binary files differ
diff --git a/TestON/TAI/src/images/horizontal.jpg b/TestON/TAI/src/images/horizontal.jpg
new file mode 100644
index 0000000..34402a8
--- /dev/null
+++ b/TestON/TAI/src/images/horizontal.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/hp.jpg b/TestON/TAI/src/images/hp.jpg
new file mode 100644
index 0000000..405e229
--- /dev/null
+++ b/TestON/TAI/src/images/hp.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/icons.zip b/TestON/TAI/src/images/icons.zip
new file mode 100644
index 0000000..8dcec50
--- /dev/null
+++ b/TestON/TAI/src/images/icons.zip
Binary files differ
diff --git a/TestON/TAI/src/images/image.png b/TestON/TAI/src/images/image.png
new file mode 100644
index 0000000..c7aa539
--- /dev/null
+++ b/TestON/TAI/src/images/image.png
Binary files differ
diff --git a/TestON/TAI/src/images/images.jpg b/TestON/TAI/src/images/images.jpg
new file mode 100644
index 0000000..42e8b51
--- /dev/null
+++ b/TestON/TAI/src/images/images.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/increaseFont.png b/TestON/TAI/src/images/increaseFont.png
new file mode 100644
index 0000000..020a56d
--- /dev/null
+++ b/TestON/TAI/src/images/increaseFont.png
Binary files differ
diff --git a/TestON/TAI/src/images/insert_table.png b/TestON/TAI/src/images/insert_table.png
new file mode 100644
index 0000000..5cf8f24
--- /dev/null
+++ b/TestON/TAI/src/images/insert_table.png
Binary files differ
diff --git a/TestON/TAI/src/images/interpreter.jpg b/TestON/TAI/src/images/interpreter.jpg
new file mode 100644
index 0000000..a89f79a
--- /dev/null
+++ b/TestON/TAI/src/images/interpreter.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/italics.png b/TestON/TAI/src/images/italics.png
new file mode 100644
index 0000000..8482ac8
--- /dev/null
+++ b/TestON/TAI/src/images/italics.png
Binary files differ
diff --git a/TestON/TAI/src/images/loading.gif b/TestON/TAI/src/images/loading.gif
new file mode 100644
index 0000000..8114457
--- /dev/null
+++ b/TestON/TAI/src/images/loading.gif
Binary files differ
diff --git a/TestON/TAI/src/images/loading6.gif b/TestON/TAI/src/images/loading6.gif
new file mode 100644
index 0000000..29119cf
--- /dev/null
+++ b/TestON/TAI/src/images/loading6.gif
Binary files differ
diff --git a/TestON/TAI/src/images/log.jpg b/TestON/TAI/src/images/log.jpg
new file mode 100644
index 0000000..dbb2523
--- /dev/null
+++ b/TestON/TAI/src/images/log.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/logo3.jpg b/TestON/TAI/src/images/logo3.jpg
new file mode 100644
index 0000000..06e6f54
--- /dev/null
+++ b/TestON/TAI/src/images/logo3.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/magicWand.png b/TestON/TAI/src/images/magicWand.png
new file mode 100644
index 0000000..2db9bae
--- /dev/null
+++ b/TestON/TAI/src/images/magicWand.png
Binary files differ
diff --git a/TestON/TAI/src/images/mail.jpg b/TestON/TAI/src/images/mail.jpg
new file mode 100644
index 0000000..271bce1
--- /dev/null
+++ b/TestON/TAI/src/images/mail.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/mastercard.png b/TestON/TAI/src/images/mastercard.png
new file mode 100644
index 0000000..48d10ce
--- /dev/null
+++ b/TestON/TAI/src/images/mastercard.png
Binary files differ
diff --git a/TestON/TAI/src/images/mininet.jpg b/TestON/TAI/src/images/mininet.jpg
new file mode 100644
index 0000000..667ae6f
--- /dev/null
+++ b/TestON/TAI/src/images/mininet.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/mobile.png b/TestON/TAI/src/images/mobile.png
new file mode 100644
index 0000000..376beb0
--- /dev/null
+++ b/TestON/TAI/src/images/mobile.png
Binary files differ
diff --git a/TestON/TAI/src/images/new.png b/TestON/TAI/src/images/new.png
new file mode 100644
index 0000000..5f61858
--- /dev/null
+++ b/TestON/TAI/src/images/new.png
Binary files differ
diff --git a/TestON/TAI/src/images/new1.png b/TestON/TAI/src/images/new1.png
new file mode 100644
index 0000000..2061b56
--- /dev/null
+++ b/TestON/TAI/src/images/new1.png
Binary files differ
diff --git a/TestON/TAI/src/images/newIcon.jpg b/TestON/TAI/src/images/newIcon.jpg
new file mode 100644
index 0000000..935d7e4
--- /dev/null
+++ b/TestON/TAI/src/images/newIcon.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/newImage.png b/TestON/TAI/src/images/newImage.png
new file mode 100644
index 0000000..b085fb7
--- /dev/null
+++ b/TestON/TAI/src/images/newImage.png
Binary files differ
diff --git a/TestON/TAI/src/images/newOrder.png b/TestON/TAI/src/images/newOrder.png
new file mode 100644
index 0000000..bd8f8ff
--- /dev/null
+++ b/TestON/TAI/src/images/newOrder.png
Binary files differ
diff --git a/TestON/TAI/src/images/nextStep.jpg b/TestON/TAI/src/images/nextStep.jpg
new file mode 100644
index 0000000..28d9db0
--- /dev/null
+++ b/TestON/TAI/src/images/nextStep.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/noResult.png b/TestON/TAI/src/images/noResult.png
new file mode 100644
index 0000000..9c5d7a5
--- /dev/null
+++ b/TestON/TAI/src/images/noResult.png
Binary files differ
diff --git a/TestON/TAI/src/images/notepad.jpeg b/TestON/TAI/src/images/notepad.jpeg
new file mode 100644
index 0000000..d03410d
--- /dev/null
+++ b/TestON/TAI/src/images/notepad.jpeg
Binary files differ
diff --git a/TestON/TAI/src/images/notepad.png b/TestON/TAI/src/images/notepad.png
new file mode 100644
index 0000000..0de1325
--- /dev/null
+++ b/TestON/TAI/src/images/notepad.png
Binary files differ
diff --git a/TestON/TAI/src/images/open.png b/TestON/TAI/src/images/open.png
new file mode 100644
index 0000000..60440a7
--- /dev/null
+++ b/TestON/TAI/src/images/open.png
Binary files differ
diff --git a/TestON/TAI/src/images/parameter.jpg b/TestON/TAI/src/images/parameter.jpg
new file mode 100644
index 0000000..8bf4f2b
--- /dev/null
+++ b/TestON/TAI/src/images/parameter.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/params.jpeg b/TestON/TAI/src/images/params.jpeg
new file mode 100644
index 0000000..114be95
--- /dev/null
+++ b/TestON/TAI/src/images/params.jpeg
Binary files differ
diff --git a/TestON/TAI/src/images/params.png b/TestON/TAI/src/images/params.png
new file mode 100644
index 0000000..f9c5fea
--- /dev/null
+++ b/TestON/TAI/src/images/params.png
Binary files differ
diff --git a/TestON/TAI/src/images/pass.png b/TestON/TAI/src/images/pass.png
new file mode 100644
index 0000000..9d81ddc
--- /dev/null
+++ b/TestON/TAI/src/images/pass.png
Binary files differ
diff --git a/TestON/TAI/src/images/paxterra_logo.jpg b/TestON/TAI/src/images/paxterra_logo.jpg
new file mode 100644
index 0000000..1e456e4
--- /dev/null
+++ b/TestON/TAI/src/images/paxterra_logo.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/paypal.png b/TestON/TAI/src/images/paypal.png
new file mode 100644
index 0000000..245df6d
--- /dev/null
+++ b/TestON/TAI/src/images/paypal.png
Binary files differ
diff --git a/TestON/TAI/src/images/pdf.png b/TestON/TAI/src/images/pdf.png
new file mode 100644
index 0000000..0c65ce2
--- /dev/null
+++ b/TestON/TAI/src/images/pdf.png
Binary files differ
diff --git a/TestON/TAI/src/images/play.ico b/TestON/TAI/src/images/play.ico
new file mode 100644
index 0000000..3ec2033
--- /dev/null
+++ b/TestON/TAI/src/images/play.ico
Binary files differ
diff --git a/TestON/TAI/src/images/play.png b/TestON/TAI/src/images/play.png
new file mode 100644
index 0000000..3ec2033
--- /dev/null
+++ b/TestON/TAI/src/images/play.png
Binary files differ
diff --git a/TestON/TAI/src/images/playImg.jpg b/TestON/TAI/src/images/playImg.jpg
new file mode 100644
index 0000000..cc3b7cd
--- /dev/null
+++ b/TestON/TAI/src/images/playImg.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/pm.png b/TestON/TAI/src/images/pm.png
new file mode 100644
index 0000000..4dbea1d
--- /dev/null
+++ b/TestON/TAI/src/images/pm.png
Binary files differ
diff --git a/TestON/TAI/src/images/pox.jpg b/TestON/TAI/src/images/pox.jpg
new file mode 100644
index 0000000..9292dec
--- /dev/null
+++ b/TestON/TAI/src/images/pox.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/print.png b/TestON/TAI/src/images/print.png
new file mode 100644
index 0000000..7fe0de2
--- /dev/null
+++ b/TestON/TAI/src/images/print.png
Binary files differ
diff --git a/TestON/TAI/src/images/progress.png b/TestON/TAI/src/images/progress.png
new file mode 100644
index 0000000..0146a34
--- /dev/null
+++ b/TestON/TAI/src/images/progress.png
Binary files differ
diff --git a/TestON/TAI/src/images/project.jpeg b/TestON/TAI/src/images/project.jpeg
new file mode 100644
index 0000000..f5fd85d
--- /dev/null
+++ b/TestON/TAI/src/images/project.jpeg
Binary files differ
diff --git a/TestON/TAI/src/images/project_1.jpeg b/TestON/TAI/src/images/project_1.jpeg
new file mode 100644
index 0000000..39d473a
--- /dev/null
+++ b/TestON/TAI/src/images/project_1.jpeg
Binary files differ
diff --git a/TestON/TAI/src/images/project_2.jpeg b/TestON/TAI/src/images/project_2.jpeg
new file mode 100644
index 0000000..39d473a
--- /dev/null
+++ b/TestON/TAI/src/images/project_2.jpeg
Binary files differ
diff --git a/TestON/TAI/src/images/py.jpg b/TestON/TAI/src/images/py.jpg
new file mode 100644
index 0000000..55b2917
--- /dev/null
+++ b/TestON/TAI/src/images/py.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/redo.png b/TestON/TAI/src/images/redo.png
new file mode 100644
index 0000000..4fe6c7f
--- /dev/null
+++ b/TestON/TAI/src/images/redo.png
Binary files differ
diff --git a/TestON/TAI/src/images/remotevm.jpg b/TestON/TAI/src/images/remotevm.jpg
new file mode 100644
index 0000000..0c2db6e
--- /dev/null
+++ b/TestON/TAI/src/images/remotevm.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/report.jpeg b/TestON/TAI/src/images/report.jpeg
new file mode 100644
index 0000000..80b4f33
--- /dev/null
+++ b/TestON/TAI/src/images/report.jpeg
Binary files differ
diff --git a/TestON/TAI/src/images/reset.jpg b/TestON/TAI/src/images/reset.jpg
new file mode 100644
index 0000000..4b0b3e7
--- /dev/null
+++ b/TestON/TAI/src/images/reset.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/reset123.jpg b/TestON/TAI/src/images/reset123.jpg
new file mode 100644
index 0000000..82e4bd3
--- /dev/null
+++ b/TestON/TAI/src/images/reset123.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/reset2.jpg b/TestON/TAI/src/images/reset2.jpg
new file mode 100644
index 0000000..7944535
--- /dev/null
+++ b/TestON/TAI/src/images/reset2.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/reset3.jpg b/TestON/TAI/src/images/reset3.jpg
new file mode 100644
index 0000000..df33a06
--- /dev/null
+++ b/TestON/TAI/src/images/reset3.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/run.jpg b/TestON/TAI/src/images/run.jpg
new file mode 100644
index 0000000..12497ea
--- /dev/null
+++ b/TestON/TAI/src/images/run.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/save.png b/TestON/TAI/src/images/save.png
new file mode 100644
index 0000000..ed3da6d
--- /dev/null
+++ b/TestON/TAI/src/images/save.png
Binary files differ
diff --git a/TestON/TAI/src/images/saveAll.jpg b/TestON/TAI/src/images/saveAll.jpg
new file mode 100644
index 0000000..b3eea73
--- /dev/null
+++ b/TestON/TAI/src/images/saveAll.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/session.png b/TestON/TAI/src/images/session.png
new file mode 100644
index 0000000..ad03026
--- /dev/null
+++ b/TestON/TAI/src/images/session.png
Binary files differ
diff --git a/TestON/TAI/src/images/showlog.jpg b/TestON/TAI/src/images/showlog.jpg
new file mode 100644
index 0000000..880d901
--- /dev/null
+++ b/TestON/TAI/src/images/showlog.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/subscript.png b/TestON/TAI/src/images/subscript.png
new file mode 100644
index 0000000..69cd15c
--- /dev/null
+++ b/TestON/TAI/src/images/subscript.png
Binary files differ
diff --git a/TestON/TAI/src/images/superscript.png b/TestON/TAI/src/images/superscript.png
new file mode 100644
index 0000000..2fb2a7c
--- /dev/null
+++ b/TestON/TAI/src/images/superscript.png
Binary files differ
diff --git a/TestON/TAI/src/images/switch.jpg b/TestON/TAI/src/images/switch.jpg
new file mode 100644
index 0000000..ac458a4
--- /dev/null
+++ b/TestON/TAI/src/images/switch.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/switch.png b/TestON/TAI/src/images/switch.png
new file mode 100644
index 0000000..a4f3fc4
--- /dev/null
+++ b/TestON/TAI/src/images/switch.png
Binary files differ
diff --git a/TestON/TAI/src/images/switchVM.png b/TestON/TAI/src/images/switchVM.png
new file mode 100644
index 0000000..179367f5
--- /dev/null
+++ b/TestON/TAI/src/images/switchVM.png
Binary files differ
diff --git a/TestON/TAI/src/images/terminal.png b/TestON/TAI/src/images/terminal.png
new file mode 100644
index 0000000..344d048
--- /dev/null
+++ b/TestON/TAI/src/images/terminal.png
Binary files differ
diff --git a/TestON/TAI/src/images/testbed.jpg b/TestON/TAI/src/images/testbed.jpg
new file mode 100644
index 0000000..e554170
--- /dev/null
+++ b/TestON/TAI/src/images/testbed.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/testname.jpg b/TestON/TAI/src/images/testname.jpg
new file mode 100644
index 0000000..4d52dfe
--- /dev/null
+++ b/TestON/TAI/src/images/testname.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/tool.jpg b/TestON/TAI/src/images/tool.jpg
new file mode 100644
index 0000000..efefad4
--- /dev/null
+++ b/TestON/TAI/src/images/tool.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/topo.png b/TestON/TAI/src/images/topo.png
new file mode 100644
index 0000000..120589d
--- /dev/null
+++ b/TestON/TAI/src/images/topo.png
Binary files differ
diff --git a/TestON/TAI/src/images/tpl.png b/TestON/TAI/src/images/tpl.png
new file mode 100644
index 0000000..0fc643b
--- /dev/null
+++ b/TestON/TAI/src/images/tpl.png
Binary files differ
diff --git a/TestON/TAI/src/images/underline.png b/TestON/TAI/src/images/underline.png
new file mode 100644
index 0000000..90d0df2
--- /dev/null
+++ b/TestON/TAI/src/images/underline.png
Binary files differ
diff --git a/TestON/TAI/src/images/verticalLine.jpg b/TestON/TAI/src/images/verticalLine.jpg
new file mode 100644
index 0000000..fbe4f1c
--- /dev/null
+++ b/TestON/TAI/src/images/verticalLine.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/visa.png b/TestON/TAI/src/images/visa.png
new file mode 100644
index 0000000..7ab7ee0
--- /dev/null
+++ b/TestON/TAI/src/images/visa.png
Binary files differ
diff --git a/TestON/TAI/src/images/vyatta-logo.jpg b/TestON/TAI/src/images/vyatta-logo.jpg
new file mode 100644
index 0000000..26da19e
--- /dev/null
+++ b/TestON/TAI/src/images/vyatta-logo.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/vyatta.jpg b/TestON/TAI/src/images/vyatta.jpg
new file mode 100644
index 0000000..3dc7c42
--- /dev/null
+++ b/TestON/TAI/src/images/vyatta.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/windows.jpg b/TestON/TAI/src/images/windows.jpg
new file mode 100644
index 0000000..861cadb
--- /dev/null
+++ b/TestON/TAI/src/images/windows.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/www2.jpg b/TestON/TAI/src/images/www2.jpg
new file mode 100644
index 0000000..61af702
--- /dev/null
+++ b/TestON/TAI/src/images/www2.jpg
Binary files differ
diff --git a/TestON/TAI/src/images/yahoo.png b/TestON/TAI/src/images/yahoo.png
new file mode 100644
index 0000000..6f5788d
--- /dev/null
+++ b/TestON/TAI/src/images/yahoo.png
Binary files differ
diff --git a/TestON/TAI/src/tai_ofa/AddParams.java b/TestON/TAI/src/tai_ofa/AddParams.java
new file mode 100644
index 0000000..8d35046
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/AddParams.java
@@ -0,0 +1,435 @@
+/*
+
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package tai_ofa;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Observable;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.event.ActionEvent;
+import javafx.event.Event;
+import javafx.event.EventHandler;
+import javafx.geometry.Insets;
+import javafx.geometry.Orientation;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.control.SplitPane;
+import javafx.scene.control.Tab;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableColumn.CellEditEvent;
+import javafx.scene.control.TableView;
+import javafx.scene.control.TextField;
+import javafx.scene.control.TextFieldBuilder;
+import javafx.scene.control.TreeItem;
+import javafx.scene.control.TreeView;
+import javafx.scene.control.cell.PropertyValueFactory;
+import javafx.scene.control.cell.TextFieldTableCell;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Pane;
+import javafx.scene.layout.VBox;
+import javafx.scene.paint.Color;
+import javafx.scene.text.Font;
+import javafx.scene.text.Text;
+import javafx.stage.Stage;
+
+/**
+ *
+ * @author Raghav Kashyap (raghavkashyap@paxterrasolutions.com)
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+
+ */
+public class AddParams {
+
+    TAI_OFA referenceOFA;
+    boolean splitFlag = false;
+    Map<String, Object> paramsHash;
+    TreeView<String> paramsTreeView;
+    TextField Value, tableAttrib, tableValue;
+    TableView<ParamsAttribute> attributeTable;
+    ObservableList<ParamsAttribute> data;
+    Button save, Cancel, edit, add, saveParams;
+    HBox buttonBox, tableViewBox, baseLeftPane;
+    VBox box, buttonTableVBox;
+    GridPane buttonBoxPane, baseRightPane;
+    TreeItem<String> params;
+    Pane tableViewPane;
+    Text Heading;
+    String tabValue, tabs;
+    OFAWizard wizard;
+    OFAFileOperations fileOperations;
+    Tab baseTab;
+    Button delete;
+
+    public void setOFA(TAI_OFA ofa) {
+        this.referenceOFA = ofa;
+    }
+
+    public void getNewParams() {
+        baseTab = new Tab();
+        paramsHash = new HashMap<String, Object>();
+        fileOperations = new OFAFileOperations();
+        final SplitPane basePane = new SplitPane();
+        basePane.setOrientation(Orientation.HORIZONTAL);
+        baseLeftPane = new HBox(30);
+        params = new TreeItem<String>();
+        params.setValue("params");
+        TreeItem<String> log_dir = new TreeItem<String>();
+        log_dir.setValue("log_dir");
+        ImageView logIView = new ImageView(new Image("images/parameter.jpg", 20, 20, true, true));
+        logIView.setId("/home/paxterra/");
+        log_dir.setGraphic(logIView);
+        TreeItem<String> mail = new TreeItem<String>();
+        mail.setValue("mail");
+        ImageView mailIView = new ImageView(new Image("images/parameter.jpg", 20, 20, true, true));
+        mailIView.setId("raghavkashyap@paxterrasolution.com");
+        mail.setGraphic(mailIView);
+        TreeItem<String> testcases = new TreeItem<String>();
+        testcases.setValue("testcases");
+        ImageView testIView = new ImageView(new Image("images/parameter.jpg", 20, 20, true, true));
+        testIView.setId("1");
+        testcases.setGraphic(testIView);
+        data = FXCollections.observableArrayList();
+        params.getChildren().addAll(testcases, mail, log_dir);
+        paramsTreeView = new TreeView<String>(params);
+        saveParams = new Button("Save");
+        delete = new Button("Delete");
+        baseLeftPane.getChildren().addAll(paramsTreeView, saveParams, delete);
+        baseRightPane = new GridPane();
+        Value = TextFieldBuilder.create().build();
+        delete.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                removeParamsValue(paramsTreeView.getSelectionModel().getSelectedItem());
+            }
+        });
+
+        saveParams.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                tabs = getParams(params);
+                referenceOFA.paramsFileContent = tabs;
+                wizard = new OFAWizard(referenceOFA.projectExplorerTree, 2, referenceOFA.projectExplorerTree.getChildren(), referenceOFA.projectExplorerTreeView);
+                wizard.setOFA(referenceOFA);
+                try {
+                    wizard.start(new Stage());
+                } catch (Exception ex) {
+                    Logger.getLogger(AddParams.class.getName()).log(Level.SEVERE, null, ex);
+                }
+
+            }
+        });
+        save = new Button("Save");
+        Cancel = new Button("Cancel");
+        edit = new Button("Edit");
+        attributeTable = new TableView<ParamsAttribute>();
+        attributeTable.setEditable(true);
+        TableColumn attribColumn = new TableColumn("Attribute");
+        attribColumn.setCellValueFactory(new PropertyValueFactory<ParamsAttribute, String>("Attribute"));
+        TableColumn valueColumn = new TableColumn("Value");
+        valueColumn.setCellValueFactory(new PropertyValueFactory<ParamsAttribute, String>("Values"));
+        attributeTable.setItems(data);
+        attributeTable.getColumns().addAll(attribColumn, valueColumn);
+        baseRightPane.setPadding(new Insets(30, 0, 10, 30));
+        baseRightPane.prefHeight(referenceOFA.scene.heightProperty().get());
+        baseRightPane.setVgap(9);
+        baseRightPane.add(new Label("Value :"), 4, 4);
+        baseRightPane.add(Value, 5, 4);
+        box = new VBox();
+        buttonBox = new HBox();
+        buttonBoxPane = new GridPane();
+        buttonBoxPane.setPadding(new Insets(30, 0, 10, 30));
+        buttonBoxPane.setHgap(3);
+        buttonBoxPane.add(save, 2, 7);
+        buttonBoxPane.add(Cancel, 4, 7);
+        buttonBoxPane.add(edit, 6, 7);
+        buttonBox.getChildren().addAll(buttonBoxPane);
+        tableAttrib = TextFieldBuilder.create().build();
+        tableValue = TextFieldBuilder.create().build();
+        add = new Button("Add");
+        tableViewPane = new Pane();
+        buttonTableVBox = new VBox();
+        tableViewBox = new HBox();
+        tableViewBox.getChildren().addAll(tableAttrib, tableValue, add);
+        buttonTableVBox.getChildren().addAll(attributeTable);
+        box.getChildren().addAll(baseRightPane, buttonTableVBox, buttonBoxPane);
+
+        attributeTable.setEditable(true);
+        attribColumn.setCellFactory(TextFieldTableCell.forTableColumn());
+        attribColumn.setOnEditCommit(new EventHandler<CellEditEvent<ParamsAttribute, String>>() {
+            @Override
+            public void handle(CellEditEvent<ParamsAttribute, String> t) {
+
+                for (int i = 0; i < paramsTreeView.getSelectionModel().getSelectedItem().getChildren().size(); i++) {
+
+                    if (paramsTreeView.getSelectionModel().getSelectedItem().getChildren().get(i).getValue().equals(t.getOldValue())) {
+                        paramsTreeView.getSelectionModel().getSelectedItem().getChildren().get(i).setValue(t.getNewValue());
+                    }
+                }
+                ((ParamsAttribute) t.getTableView().getItems().get(
+                        t.getTablePosition().getRow())).setAttribute(t.getNewValue());
+
+            }
+        });
+
+        valueColumn.setCellFactory(TextFieldTableCell.forTableColumn());
+        valueColumn.setOnEditCommit(new EventHandler<CellEditEvent<ParamsAttribute, String>>() {
+            @Override
+            public void handle(CellEditEvent<ParamsAttribute, String> t) {
+                for (int i = 0; i < paramsTreeView.getSelectionModel().getSelectedItem().getChildren().size(); i++) {
+                    if (paramsTreeView.getSelectionModel().getSelectedItem().getChildren().get(i).getValue().equals(t.getOldValue())) {
+                        paramsTreeView.getSelectionModel().getSelectedItem().getChildren().get(i).getGraphic().setId(t.getNewValue());
+                    }
+                }
+                ((ParamsAttribute) t.getTableView().getItems().get(
+                        t.getTablePosition().getRow())).setValues(t.getNewValue());
+            }
+        });
+
+        Value.setOnKeyReleased(new EventHandler<KeyEvent>() {
+            @Override
+            public void handle(KeyEvent t) {
+                if (Value.getText().isEmpty()) {
+                    edit.setDisable(false);
+                } else {
+                    edit.setDisable(true);
+                }
+            }
+        });
+
+        Cancel.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                basePane.getItems().removeAll(box);
+                splitFlag = false;
+                baseRightPane.getChildren().remove(Heading);
+                edit.setDisable(false);
+            }
+        });
+
+        save.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                String selected = paramsTreeView.getSelectionModel().getSelectedItem().getValue();
+                TreeItem<String> selectedTreeItem = paramsTreeView.getSelectionModel().getSelectedItem();
+                String attribVal = Value.getText();
+                basePane.getItems().removeAll(box);
+                splitFlag = false;
+                Map<String, Object> prevParent = new HashMap<String, Object>();
+                ArrayList<String> names = new ArrayList<String>();
+                if (!edit.isDisabled()) {
+                    for (int i = 0; i < attributeTable.getItems().size(); i++) {
+                        ParamsAttribute table = attributeTable.getItems().get(i);
+                        if (selectedTreeItem.getChildren().size() == 0) {
+                            TreeItem<String> childNode = new TreeItem<String>();
+                            childNode.setValue(table.getAttribute());
+                            selectedTreeItem.getChildren().add(childNode);
+                            selectedTreeItem.setExpanded(true);
+                            Image chidlImage = new Image("images/parameter.jpg", 20, 20, true, true);
+                            ImageView childImageView = new ImageView();
+                            childImageView.setImage(chidlImage);
+                            childImageView.setId(table.getValues());
+                            childNode.setGraphic(childImageView);
+                        } else if (selectedTreeItem.getChildren().size() > 0) {
+                            names.clear();
+                            for (int index = 0; index < selectedTreeItem.getChildren().size(); index++) {
+                                names.add(selectedTreeItem.getChildren().get(index).getValue());
+                            }
+                            if (!names.contains(table.getAttribute())) {
+                                TreeItem<String> childNode = new TreeItem<String>();
+                                childNode.setValue(table.getAttribute());
+                                selectedTreeItem.getChildren().addAll(childNode);
+                                selectedTreeItem.setExpanded(true);
+                                Image chidlImage = new Image("images/parameter.jpg", 20, 20, true, true);
+                                ImageView childImageView = new ImageView();
+                                childImageView.setImage(chidlImage);
+                                childImageView.setId(table.getValues());
+                                childNode.setGraphic(childImageView);
+                            }
+                        }
+                    }
+                } else {
+                    TreeItem<String> selectTreeItem = paramsTreeView.getSelectionModel().getSelectedItem();
+                    if (!Value.getText().isEmpty()) {
+                        paramsTreeView.getSelectionModel().getSelectedItem().getGraphic().setId(Value.getText());
+                    }
+                }
+                baseRightPane.getChildren().remove(Heading);
+                buttonTableVBox.getChildren().removeAll(tableViewBox);
+                Value.clear();
+            }
+        });
+
+        add.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+
+                if (tableAttrib.getText().isEmpty() && tableValue.getText().isEmpty()) {
+                } else {
+                    data.add(new ParamsAttribute(tableAttrib.getText(), tableValue.getText()));
+                    tableAttrib.clear();
+                    tableValue.clear();
+                }
+            }
+        });
+
+
+        edit.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+
+                buttonTableVBox.getChildren().addAll(tableViewBox);
+
+                Value.setEditable(false);
+
+            }
+        });
+
+        basePane.getItems().addAll(baseLeftPane);
+        paramsTreeView.setOnMouseClicked(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent args0) {
+                String selected = paramsTreeView.getSelectionModel().getSelectedItem().getValue();
+                TreeItem<String> selectItem = paramsTreeView.getSelectionModel().getSelectedItem();
+                if (args0.getClickCount() == 2 & !splitFlag) {
+                    Value.setEditable(true);
+                    Heading = new Text(selected);
+                    Heading.setFont(Font.font("Arial", 20));
+                    Heading.setFill(Color.BLUE);
+                    baseRightPane.add(Heading, 6, 1);
+
+                    if (selectItem.isLeaf()) {
+                        Value.setDisable(false);
+                        if (!selectItem.getGraphic().getId().equals("")) {
+                            basePane.getItems().addAll(box);
+                            splitFlag = true;
+                            Value.setText(selectItem.getGraphic().getId());
+                            edit.setDisable(true);
+                            data.clear();
+                        } else {
+                            basePane.getItems().addAll(box);
+                            splitFlag = true;
+                            Value.clear();
+                            edit.setDisable(false);
+                            data.clear();
+                        }
+                    } else if (!selectItem.isLeaf()) {
+                        Value.clear();
+                        Value.setDisable(true);
+                        basePane.getItems().addAll(box);
+                        splitFlag = true;
+                        data.clear();
+                        for (int i = 0; i < selectItem.getChildren().size(); i++) {
+
+                            data.add(new ParamsAttribute(selectItem.getChildren().get(i).getValue(), selectItem.getChildren().get(i).getGraphic().getId()));
+                        }
+                    }
+
+                }
+            }
+        });
+        basePane.prefWidthProperty().bind(referenceOFA.scene.widthProperty().subtract(300));
+        basePane.prefHeightProperty().bind(referenceOFA.scene.heightProperty().subtract(120));
+        baseTab.setContent(basePane);
+        baseTab.setText("Unnamed.params");
+        referenceOFA.editorTabPane.getTabs().addAll(baseTab);
+    }
+
+    public String getParams(TreeItem<String> treeNode) {
+        tabValue = "";
+        tabValue = tabValue + "<" + treeNode.getValue() + ">\n";
+        if (!treeNode.isLeaf()) {
+            for (int i = 0; i < treeNode.getChildren().size(); i++) {
+                if (treeNode.getChildren().get(i).isLeaf()) {
+                    tabValue = tabValue + "\n<" + treeNode.getChildren().get(i).getValue() + ">" + treeNode.getChildren().get(i).getGraphic().getId()
+                            + "</" + treeNode.getChildren().get(i).getValue() + ">\n";
+                } else if (!treeNode.getChildren().get(i).isLeaf()) {
+                    int index = 0;
+                    tabValue = tabValue + "\n<" + treeNode.getChildren().get(i).getValue() + ">\n";
+                    while (index < treeNode.getChildren().get(i).getChildren().size()) {
+                        tabValue = tabValue + getParams(treeNode.getChildren().get(i).getChildren().get(index));
+                        index++;
+                    }
+                    tabValue = tabValue + "\n</" + treeNode.getChildren().get(i).getValue() + ">\n";
+                }
+            }
+        } else if (treeNode.isLeaf()) {
+            tabValue = tabValue + treeNode.getGraphic().getId();
+        }
+        tabValue = tabValue + "\n</" + treeNode.getValue() + ">";
+        return tabValue;
+    }
+
+    public void removeParamsValue(TreeItem treeItem) {
+        for (int i = 0; i < paramsTreeView.getRoot().getChildren().size(); i++) {
+            if (paramsTreeView.getRoot().getChildren().get(i).isLeaf()) {
+                if (paramsTreeView.getRoot().getChildren().get(i).getValue().equals(treeItem.getValue())) {
+                    paramsTreeView.getRoot().getChildren().remove(paramsTreeView.getRoot().getChildren().get(i));
+                }
+            } else if (!paramsTreeView.getRoot().getChildren().get(i).isLeaf()) {
+                if (paramsTreeView.getRoot().getChildren().get(i).getValue().equals(treeItem.getValue())) {
+                    paramsTreeView.getRoot().getChildren().remove(paramsTreeView.getRoot().getChildren().get(i));
+                } else {
+                    for (int index = 0; index < paramsTreeView.getRoot().getChildren().get(i).getChildren().size(); index++) {
+                        if (paramsTreeView.getRoot().getChildren().get(i).getChildren().get(index).getValue().equals(treeItem.getValue())) {
+                            paramsTreeView.getRoot().getChildren().get(i).getChildren().remove(paramsTreeView.getRoot().getChildren().get(i).getChildren().get(index));
+                        }
+                    }
+                }
+            }
+        }
+
+    }
+
+    public static class ParamsAttribute {
+        private final SimpleStringProperty Attributes;
+        private final SimpleStringProperty Values;
+
+        private ParamsAttribute(String attrib, String val) {
+            this.Attributes = new SimpleStringProperty(attrib);
+            this.Values = new SimpleStringProperty(val);
+        }
+
+        public String getAttribute() {
+            return Attributes.get();
+        }
+
+        public void setAttribute(String attrib) {
+            Attributes.set(attrib);
+        }
+
+        public String getValues() {
+            return Values.get();
+        }
+
+        public void setValues(String val) {
+            Values.set(val);
+        }
+    }
+}
diff --git a/TestON/TAI/src/tai_ofa/CodeEditor.java b/TestON/TAI/src/tai_ofa/CodeEditor.java
new file mode 100644
index 0000000..c645aac
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/CodeEditor.java
@@ -0,0 +1,220 @@
+package tai_ofa;
+
+import java.util.Locale;
+import javafx.scene.layout.StackPane;
+import javafx.scene.web.WebView;
+import javax.print.Doc;
+import javax.swing.tree.DefaultTreeCellEditor;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/*
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+
+*/
+
+public class CodeEditor extends StackPane {
+
+    /**
+     * a webview used to encapsulate the JavaScript.
+     */
+    final WebView webview = new WebView();
+    /**
+     * a snapshot of the code to be edited kept for easy initialization and
+     * reversion of editable code.
+     */
+    private String editingCode;
+    /**
+     * a template for editing code - this can be changed to any template derived
+     * from the supported modes at java to allow syntax highlighted editing of a
+     * wide variety of languages.
+     */
+    TAILocale label = new TAILocale(new Locale("en", "EN"));
+    String editorScriptsPath = label.OFAHarnessPath;
+    private final String editingTemplate =
+            "<!doctype html>"
+            + "<html>"
+            + "<head>"
+            + " <link rel=\"stylesheet\" href=\"file://editorScriptPath/codemirror.css\">".replace("editorScriptPath", editorScriptsPath + "/EditorScripts")
+            + "  <script src=\"file://editorScriptPath/codemirror.js\"></script>".replace("editorScriptPath", editorScriptsPath + "/EditorScripts")
+            + "  <script src=\"file://editorScriptPath/clike.js\"></script>".replace("editorScriptPath", editorScriptsPath + "/EditorScripts")
+            + "  <script src=\"file://editorScriptPath/javascript-hint.js\"></script>".replace("editorScriptPath", editorScriptsPath + "/EditorScripts")
+            + "  <script src=\"file://editorScriptPath/search.js\"></script>".replace("editorScriptPath", editorScriptsPath + "/EditorScripts")
+            + "  <script src=\"file://editorScriptPath/dialog.js\"></script>".replace("editorScriptPath", editorScriptsPath + "/EditorScripts")
+            + "  <script src=\"file://editorScriptPath/searchcursor.js\"></script>".replace("editorScriptPath", editorScriptsPath + "/EditorScripts")
+            + "  <script src=\"file://editorScriptPath/simple-hint.js\"></script>".replace("editorScriptPath", editorScriptsPath + "/EditorScripts")
+            + " <link rel=\"stylesheet\" href=\"file://editorScriptPath/simple-hint.css\">".replace("editorScriptPath", editorScriptsPath + "/EditorScripts")
+            + "  <script src=\"file://editorScriptPath/javascript-hint.js\"></script>".replace("editorScriptPath", editorScriptsPath + "/EditorScripts")
+            + "  <script src=\"file://editorScriptPath/foldcode.js\"></script>".replace("editorScriptPath", editorScriptsPath + "/EditorScripts")
+            + "  <script src=\"file://editorScriptPath/perl.js\"></script>".replace("editorScriptPath", editorScriptsPath + "/EditorScripts")
+            + "  <script src=\"file://editorScriptPath/xml.js\"></script>".replace("editorScriptPath", editorScriptsPath + "/EditorScripts")
+            + "</head>"
+            + "<body>"
+            + "<form><textarea id=\"code\" name=\"code\">\n"
+            + "${code}"
+            + "</textarea></form>"
+            + "<script>"
+            + "var editor;"
+            + "editor = CodeMirror.fromTextArea(document.getElementById(\"code\"), {"
+            + "mode: \"perl\","
+            + "lineNumbers: true,"
+            + "  });"
+            + "</script>"
+            + "</body>"
+            + "</html>";
+
+    /**
+     * applies the editing template to the editing code to create the
+     * html+javascript source for a code editor.
+     */
+    private String applyEditingTemplate() {
+
+        editingTemplate.replace("${code}", editingCode);
+        return editingTemplate.replace("${code}", editingCode);
+
+    }
+
+    /**
+     * sets the current code in the editor and creates an editing snapshot of
+     * the code which can be reverted to.
+     */
+    public void setCode(String newCode) {
+        this.editingCode = newCode;
+        webview.getEngine().loadContent(applyEditingTemplate());
+
+        // webview.getStylesheets().add("eclipse.css");
+    }
+
+    public String getCurrentLine() {
+        return (String) webview.getEngine().executeScript("editor.getLine(editor.getCursor().line);");
+    }
+
+    public String getCurrentLineNumber() {
+
+        return webview.getEngine().executeScript("editor.getLineNumber(editor.getCursor().line);").toString();
+
+    }
+
+    public String getCurrentLine(int lineNumber) {
+        Integer lines = lineNumber;
+        return (String) webview.getEngine().executeScript("editor.getLine(line);".replace("line", lines.toString()));
+
+    }
+
+    public void setLine(int lineNumber, String text) {
+        String lineToSet = "editor.setLine(" + lineNumber + ",'lineText');";
+        webview.getEngine().executeScript(lineToSet.replace("lineText", text));
+    }
+
+    /**
+     * returns the current code in the editor and updates an editing snapshot of
+     * the code which can be reverted to.
+     */
+    public String getCodeAndSnapshot() {
+        //Document doc = webview.getEngine().getDocument();
+//            Element el = doc.getElementById("code");
+        webview.getEngine().executeScript("editor.refresh();");
+        this.editingCode = (String) webview.getEngine().executeScript("editor.getValue();");
+
+        return editingCode;
+    }
+
+    public int cursorPosfromTop() {
+        return (Integer) webview.getEngine().executeScript("editor.cursorTopPos();");
+
+    }
+
+    public int cursorPosfromLeft() {
+        return (Integer) webview.getEngine().executeScript("editor.cursorLeftPos();");
+
+    }
+
+    public String test() {
+        return (String) webview.getEngine().executeScript("editor.find();");
+
+    }
+
+    public void clearMarker(String line) {
+        int lineNumber = Integer.parseInt(line) - 1;
+        String lineNumberString = "editor.clearMarker(clearGutter);".replace("clearGutter", String.valueOf(lineNumber));
+        webview.getEngine().executeScript(lineNumberString);
+    }
+
+    public void SetError(String line, final String errorType) {
+
+        final String tooltip = "editor.setMarker(line-1, \"<a id='error' title='errorType \"  +  \"'><img src='file://editorScriptPath/Delete.png'/></a>%N%\"); ".replace("editorScriptPath", editorScriptsPath + "/EditorScripts");
+        Integer lineCount = (Integer) webview.getEngine().executeScript("editor.lineCount();");
+        int i;
+        for (i = 1; i <= lineCount; i++) {
+            String tooltipToExcute = tooltip.replace("line", line).replace("errorType", errorType);
+            if (!"".equals(errorType)) {
+                webview.getEngine().executeScript(tooltipToExcute);
+            }
+        }
+
+    }
+
+    public void SetWarning(String line, final String errorType) {
+
+        final String tooltip = "editor.setMarker(line-1, \"<a id='error' title='errorType \"  +  \"'><img src='file://editorScriptPath/Warning.png'/></a>%N%\"); ".replace("editorScriptPath", editorScriptsPath + "/EditorScripts");
+        Integer lineCount = (Integer) webview.getEngine().executeScript("editor.lineCount();");
+        int i;
+        for (i = 1; i <= lineCount; i++) {
+            String tooltipToExcute = tooltip.replace("line", line).replace("errorType", errorType);
+            if (!"".equals(errorType)) {
+                webview.getEngine().executeScript(tooltipToExcute);
+            }
+        }
+
+    }
+
+    public void SetInfo(String line, final String errorType) {
+
+        final String tooltip = "editor.setMarker(line-1, \"<a id='error' title='errorType \"  +  \"'><img src='file://editorScriptPath/info.jpg'/></a>%N%\"); ".replace("editorScriptPath", editorScriptsPath + "/EditorScripts");
+        Integer lineCount = (Integer) webview.getEngine().executeScript("editor.lineCount();");
+        int i;
+        for (i = 1; i <= lineCount; i++) {
+            String tooltipToExcute = tooltip.replace("line", line).replace("errorType", errorType);
+            if (!"".equals(errorType)) {
+                webview.getEngine().executeScript(tooltipToExcute);
+            }
+        }
+
+    }
+
+    /**
+     * revert edits of the code to the last edit snapshot taken.
+     */
+    public void revertEdits() {
+        setCode(editingCode);
+    }
+
+    /**
+     * Create a new code editor.
+     *
+     * @param editingCode the initial code to be edited in the code editor.
+     */
+    CodeEditor(String editingCode) {
+        this.editingCode = editingCode;
+
+        // webview.setPrefSize(650, 325);
+        //  webview.setMinSize(150, 325);
+        webview.getEngine().loadContent(applyEditingTemplate());
+
+
+        this.getChildren().add(webview);
+    }
+}
diff --git a/TestON/TAI/src/tai_ofa/CodeEditorParams.java b/TestON/TAI/src/tai_ofa/CodeEditorParams.java
new file mode 100644
index 0000000..99ed8e1
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/CodeEditorParams.java
@@ -0,0 +1,207 @@
+package tai_ofa;
+
+import com.sun.org.apache.xerces.internal.parsers.IntegratedParserConfiguration;
+import java.awt.TextArea;
+import java.util.ArrayList;
+import java.util.Locale;
+import javafx.event.EventHandler;
+import javafx.scene.Group;
+import javafx.scene.Node;
+import javafx.scene.control.Button;
+import javafx.scene.control.ContextMenu;
+import javafx.scene.control.MenuItem;
+import javafx.scene.control.Tab;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.StackPane;
+import javafx.scene.web.PopupFeatures;
+import javafx.scene.web.WebEngine;
+import javafx.scene.web.WebView;
+import javafx.util.Callback;
+import javax.swing.JOptionPane;
+
+
+/*
+ * To change this template, choose Tools | Templates and open the template in
+ * the editor.
+ */
+/**
+ *
+ * @author Raghav Kashyap (raghavkashyap@paxterrasolutions.com)
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+ * /**
+ */
+public class CodeEditorParams extends StackPane {
+
+    TAI_OFA OFAReference;
+    WebView webview = new WebView();
+    private String editingCode;
+    ContextMenu contextMenu;
+    TAILocale label = new TAILocale(new Locale("en", "EN"));
+    String editorScriptsPath = label.OFAHarnessPath;
+    private final String editingTemplate =
+            "<!doctype html>"
+            + "<html>"
+            + "<head>"
+            + " <link rel=\"stylesheet\"href=\"file://editorScriptPath/codemirror.css\">".replace("editorScriptPath", editorScriptsPath+"/EditorScripts")
+            + "  <script src=\"file://editorScriptPath/codemirror.js\"></script>".replace("editorScriptPath", editorScriptsPath+"/EditorScripts")
+            + "  <script src=\"file://editorScriptPath/foldcode.js\"></script>".replace("editorScriptPath", editorScriptsPath+"/EditorScripts")
+            + "  <script src=\"file://editorScriptPath/perl.js\"></script>".replace("editorScriptPath", editorScriptsPath+"/EditorScripts")
+            + "  <script src=\"file://editorScriptPath/xml.js\"></script>".replace("editorScriptPath", editorScriptsPath+"/EditorScripts")
+            + " <style type=\"text/css\">"
+            + "</style>"
+            + "</head>"
+            + "<body>"
+            + "<form><textarea id=\"code\" name=\"code\">\n"
+            + "${code}"
+            + "</textarea></form>"
+            + "<script>"
+            + " var foldFunc = CodeMirror.newFoldFunction(CodeMirror.tagRangeFinder);"
+            + "var editor;"
+            + "editor = CodeMirror.fromTextArea(document.getElementById(\"code\"), {"
+            + "mode: \"perl\","
+            + "     lineNumbers: true,"
+            + "onGutterClick: foldFunc,"
+            + "extraKeys: {\"Ctrl-Q\" : function(cm){foldFunc(cm, cm.getCursor().line);}}"
+            + "  });"
+            + "</script>"
+            + "</body>"
+            + "</html>";
+
+    /**
+     * applies the editing template to the editing code to create the
+     * html+javascript source for a code editor.
+     */
+    private String applyEditingTemplate() {
+        editingTemplate.replace("${code}", editingCode);        
+        return editingTemplate.replace("${code}", editingCode);
+    }
+
+    public void setOFA(TAI_OFA reference) {
+        OFAReference = reference;
+    }
+
+    /**
+     * sets the current code in the editor and creates an editing snapshot of
+     * the code which can be reverted to.
+     */
+    public void setCode(String newCode) {
+        this.editingCode = newCode;
+        webview.getEngine().loadContent(applyEditingTemplate());
+    }
+
+    public String getCurrentLine() {
+        return (String) webview.getEngine().executeScript("editor.getLine(editor.getCursor().line);");
+    }
+
+    public String getCurrentLineNumber() {
+        return webview.getEngine().executeScript("editor.getLineNumber(editor.getCursor().line);").toString();
+
+    }
+
+    public String getCurrentLine(int lineNumber) {
+        Integer lines = lineNumber;
+        return (String) webview.getEngine().executeScript("editor.getLine(line);".replace("line", lines.toString()));
+
+    }
+
+    /**
+     * returns the current code in the editor and updates an editing snapshot of
+     * the code which can be reverted to.
+     */
+    public String getCodeAndSnapshot() {
+        this.editingCode = (String) webview.getEngine().executeScript("editor.getValue();");
+        return editingCode;
+    }
+
+    public void alert() {
+        webview.getEngine().executeScript("editor.myFunction();");
+    }
+
+    public int cursorPosfromTop() {
+        return (Integer) webview.getEngine().executeScript("editor.cursorTopPos();");
+    }
+
+    public int cursorPosfromLeft() {
+        return (Integer) webview.getEngine().executeScript("editor.cursorLeftPos();");
+    }
+
+    public void clearMarker(String line) {
+        int lineNumber = Integer.parseInt(line) - 1;
+        String lineNumberString = "editor.clearMarker(clearGutter);".replace("clearGutter", String.valueOf(lineNumber));
+        webview.getEngine().executeScript(lineNumberString);
+    }
+
+    public void SetError(String line, final String errorType) {
+
+        final String tooltip = "editor.setMarker(line-1, \"<a id='error' title='errorType \"  +  \"'><img src='file://editorScriptPath/Delete.png'/></a>%N%\"); ".replace("editorScriptPath", editorScriptsPath+"/EditorScripts");
+        Integer lineCount = (Integer) webview.getEngine().executeScript("editor.lineCount();");
+        int i;
+        for (i = 1; i <= lineCount; i++) {
+            String tooltipToExcute = tooltip.replace("line", line).replace("errorType", errorType);
+            if (!"".equals(errorType)) {
+                webview.getEngine().executeScript(tooltipToExcute);
+            }
+        }
+
+    }
+
+    public void SetWarning(String line, final String errorType) {
+
+        final String tooltip = "editor.setMarker(line-1, \"<a id='error' title='errorType \"  +  \"'><img src='file://editorScriptPath/Warning.png'/></a>%N%\"); ".replace("editorScriptPath", editorScriptsPath+"/EditorScripts");
+        Integer lineCount = (Integer) webview.getEngine().executeScript("editor.lineCount();");
+        int i;
+        for (i = 1; i <= lineCount; i++) {
+            String tooltipToExcute = tooltip.replace("line", line).replace("errorType", errorType);
+            if (!"".equals(errorType)) {
+                webview.getEngine().executeScript(tooltipToExcute);
+            }
+        }
+
+    }
+
+    public void SetInfo(String line, final String errorType) {
+
+        final String tooltip = "editor.setMarker(line-1, \"<a id='error' title='errorType \"  +  \"'><img src='file://editorScriptPath/info.jpg'/></a>%N%\"); ".replace("editorScriptPath", editorScriptsPath+"/EditorScripts");
+        Integer lineCount = (Integer) webview.getEngine().executeScript("editor.lineCount();");
+        int i;
+        for (i = 1; i <= lineCount; i++) {
+            String tooltipToExcute = tooltip.replace("line", line).replace("errorType", errorType);
+            if (!"".equals(errorType)) {
+                webview.getEngine().executeScript(tooltipToExcute);
+            }
+        }
+
+    }
+
+    /**
+     * revert edits of the code to the last edit snapshot taken.
+     */
+    public void revertEdits() {
+        setCode(editingCode);
+    }
+
+    CodeEditorParams(String editingCode) {
+        this.editingCode = editingCode;
+        webview.getEngine().loadContent(applyEditingTemplate());
+        this.getChildren().add(webview);
+    }
+
+    public void contextMenu() {
+        contextMenu = new ContextMenu();
+        MenuItem myMenuItem = new MenuItem();
+        contextMenu.getItems().add(myMenuItem);
+    }
+}
diff --git a/TestON/TAI/src/tai_ofa/DraggableNode.java b/TestON/TAI/src/tai_ofa/DraggableNode.java
new file mode 100644
index 0000000..83cf191
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/DraggableNode.java
@@ -0,0 +1,82 @@
+package tai_ofa;
+
+
+import javafx.collections.ObservableList;
+import javafx.event.EventHandler;
+import javafx.scene.Parent;
+import javafx.scene.input.MouseEvent;
+
+/**
+ *
+ * @author Raghav Kashyap raghavkashyap@paxterrasolutions.com
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+
+ */
+public class DraggableNode extends Parent{
+
+    //ATTRIBUTES
+    //X AND Y postion of Node
+    double x = 0;
+    double y = 0;
+    //X AND Y position of mouse
+    double mousex=0;
+    double mousey=0;
+
+    //To make this function accessible for other Class
+    @Override
+    public ObservableList getChildren(){
+        return super.getChildren();
+    }
+
+    public DraggableNode(){
+        super();
+
+        //EventListener for MousePressed
+        onMousePressedProperty().set(new EventHandler<MouseEvent>(){
+
+            @Override
+            public void handle(MouseEvent event) {
+               //record the current mouse X and Y position on Node
+               mousex = event.getSceneX();
+               mousey= event.getSceneY();
+               //get the x and y position measure from Left-Top
+               x = getLayoutX();
+               y = getLayoutY();
+            }
+
+        });
+
+        //Event Listener for MouseDragged
+        onMouseDraggedProperty().set(new EventHandler<MouseEvent>(){
+
+            @Override
+            public void handle(MouseEvent event) {
+                //Get the exact moved X and Y
+                x += event.getSceneX()-mousex ;
+                y += event.getSceneY()-mousey ;
+
+                //set the positon of Node after calculation
+                setLayoutX(x);
+                setLayoutY(y);
+
+                //again set current Mouse x AND y position
+                mousex = event.getSceneX();
+                mousey= event.getSceneY();
+
+            }
+        });
+    }
+}
diff --git a/TestON/TAI/src/tai_ofa/ExecuteTest.java b/TestON/TAI/src/tai_ofa/ExecuteTest.java
new file mode 100644
index 0000000..d4f9197
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/ExecuteTest.java
@@ -0,0 +1,705 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package tai_ofa;
+
+/**
+ *
+ * @author Raghavkashyap (raghavkashyap@paxterra.com)
+
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+ */
+// Import the Java classes
+import com.sun.javafx.scene.layout.region.BackgroundFill;
+import com.sun.org.apache.bcel.internal.generic.LoadInstruction;
+import java.awt.TextArea;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.io.*;
+import java.net.MalformedURLException;
+import java.nio.file.WatchService;
+import java.text.SimpleDateFormat;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javafx.application.Platform;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.event.EventHandler;
+import javafx.geometry.Insets;
+import javafx.scene.chart.PieChart;
+import javafx.scene.control.Button;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.Label;
+import javafx.scene.control.Tab;
+import javafx.scene.control.TabPane;
+import javafx.scene.control.TableView;
+import javafx.scene.control.TextAreaBuilder;
+import javafx.scene.effect.BlendMode;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.ScrollEvent;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.StackPane;
+import javafx.scene.paint.Color;
+import javafx.scene.paint.Paint;
+import javafx.stage.Popup;
+import javafx.stage.Stage;
+import org.apache.xmlrpc.XmlRpcClient;
+import org.apache.xmlrpc.XmlRpcException;
+
+public class ExecuteTest {
+
+    Pattern stepPatt, casePatt, resultPatt, namePatt, summaryPatt, testStartPatt, testEndPatt, testExecutionTimePatt, testsPlannedPatt,
+            testsRunPatt, totalPassPatt, totalFailPatt, noResultPatt, totalAbortPatt, execPercentagePatt, successPercentagePatt, assertionPatt, totalreRun;
+    TableView summaryTable, finalSummaryTable, stepTable;
+    public static int noOfPassed = 0, noOfFailed = 0, noOfAborted = 0, noOfNoResult = 0, failed = 0, passed = 0, noResults = 0, aboarted = 0;
+    String summary, testStart, testEnd, testExecutionTime, testsPlanned, testsRun, totalPass,
+            totalFail, noResult, totalAbort, execPercentage, successPercentage;
+    ObservableList<SummaryTable> data;
+    ObservableList<FinalSummaryTable> finalSummaryData;
+    ObservableList<StepTable> stepSummaryData;
+    //AutoMateTestSummary summaryWindow ;
+    StackPane summaryTableRoot;
+    TreeMap<String, String> stepHash = new TreeMap<String, String>();
+    TreeMap<String, String> caseNameHash = new TreeMap<String, String>();
+    Matcher m;
+    int tableIndex = -1;
+    int stepTableIndex = -1;
+    Runnable r3;
+    Button viewLogsButton;
+    PieChart summaryChart;
+    PieChart.Data passData, failData, abortData, noResultData;
+    String selectedTest;
+    ObservableList<PieChart.Data> pieChartData;
+    javafx.scene.control.TextArea compononetLogText = TextAreaBuilder.create().build();
+    javafx.scene.control.TextArea flowVisorSessionText = TextAreaBuilder.create().build();
+    javafx.scene.control.TextArea poxSessionText = TextAreaBuilder.create().build();
+    javafx.scene.control.TextArea mininetSessionText = TextAreaBuilder.create().build();
+    Label statusImage;
+    TAILocale label = new TAILocale(Locale.ENGLISH);
+
+    public ExecuteTest(TableView summary, ObservableList<SummaryTable> dataInstance,
+            PieChart chart, TableView finalSummary, ObservableList<FinalSummaryTable> finalSummaryDataInstance,
+            Button viewLogs, ObservableList<PieChart.Data> pieChartData,
+            PieChart.Data passData, PieChart.Data failData, PieChart.Data abortData, PieChart.Data noResultData, String testName, javafx.scene.control.TextArea componentLogText,
+            TableView stepTable, ObservableList<StepTable> stepTableData, javafx.scene.control.TextArea poxText, javafx.scene.control.TextArea mininetText, javafx.scene.control.TextArea flowText) {
+        this.summaryTable = summary;
+        data = dataInstance;
+        summaryChart = chart;
+        finalSummaryTable = finalSummary;
+        finalSummaryData = finalSummaryDataInstance;
+        viewLogsButton = viewLogs;
+        this.pieChartData = pieChartData;
+        this.passData = passData;
+        this.failData = failData;
+        this.abortData = abortData;
+        this.noResultData = noResultData;
+        this.selectedTest = testName;
+        this.compononetLogText = componentLogText;
+        this.stepTable = stepTable;
+        this.stepSummaryData = stepTableData;
+        this.poxSessionText = poxText;
+        this.mininetSessionText = mininetText;
+        this.flowVisorSessionText = flowText;
+
+    }
+    String currentTestCase, testCaseName, testCaseStatus, testCaseStartTime, testCaseEndTime;
+
+    public void runTest() {
+
+
+
+        try {
+
+            summaryTable.setVisible(true);
+            getCaseName();
+            Iterator entries = caseNameHash.entrySet().iterator();
+            data = FXCollections.observableArrayList();
+            int index = 0;
+            while (entries.hasNext()) {
+                index++;
+                Map.Entry entry = (Map.Entry) entries.next();
+                String key = (String) entry.getKey();
+                String value = (String) entry.getValue();
+                Image image = new Image(getClass().getResourceAsStream("/images/loading.gif"), 10, 10, true, true);
+                data.add(new SummaryTable(new Label(key), new Label(value), new Label("", new ImageView(image)), new Label(), new Label()));
+            }
+            summaryTable.setItems(data);
+            File file = new File(selectedTest);
+            String[] runThisFile = file.getName().split("\\.");
+            try {
+                XmlRpcClient server = new XmlRpcClient("http://localhost:9000");
+                Vector params = new Vector();
+                params.add(new String(selectedTest));
+                final Object result = server.execute("runTest", params);
+                new Thread(new Runnable() {
+                    @Override
+                    public void run() {
+                        ProcessBuilder header = new ProcessBuilder("/bin/sh", "-c", "head -20 " + result.toString());
+                        Process headProcess;
+                        try {
+                            headProcess = header.start();
+                            BufferedReader inputHeader = new BufferedReader(new InputStreamReader(headProcess.getInputStream()));
+                            String lines;
+                            String totalText = "";
+                            while ((lines = inputHeader.readLine()) != null) {
+                                try {
+                                    totalText = totalText + "\n" + lines;
+                                    updateData(lines);
+                                } catch (Exception e) {
+                                }
+                            }
+                            compononetLogText.appendText(totalText);
+                            headProcess.destroy();
+                        } catch (IOException ex) {
+                            Logger.getLogger(ExecuteTest.class.getName()).log(Level.SEVERE, null, ex);
+                        }
+                        String command = "tail -f " + result.toString();
+                        File dir = new File(result.toString());
+                        String parentPath = dir.getParent();
+                        ProcessBuilder tail = new ProcessBuilder("/bin/sh", "-c", "tail -f " + result.toString());
+                        Process process;
+                        int nullcount = 0;
+                        try {
+                            while (true) {
+                                process = tail.start();
+                                BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
+                                String line;
+                                try {
+                                    while ((line = input.readLine()) != null) {
+                                        compononetLogText.appendText("\n" + line + "\n");
+                                        updateData(line);
+                                    }
+                                    if (input.readLine() == null) {
+                                        nullcount++;
+                                    }
+                                    if (nullcount == 2) {
+                                        process.destroy();
+                                    }
+
+                                } catch (Exception e) {
+                                }
+                            }
+                        } catch (IOException ex) {
+                            Logger.getLogger(ExecuteTest.class.getName()).log(Level.SEVERE, null, ex);
+                        }
+                        String poxFileName = parentPath + "/" + "POX2.session";
+                        String flowFileName = parentPath + "/" + "FlowVisor1.session";
+                        String mininetFileName = parentPath + "/" + "Mininet1.session";
+                        ProcessBuilder tailpox = new ProcessBuilder("/bin/sh", "-c", "tail -f " + poxFileName);
+                    }
+                }).start();
+
+                r3 = new Runnable() {
+                    public void run() {
+                        try {
+                            summaryChart.setVisible(true);
+                            try {
+                                pieChartData.set(0, new PieChart.Data("Pass", ExecuteTest.noOfPassed));
+                                pieChartData.set(1, new PieChart.Data("Fail", ExecuteTest.noOfFailed));
+                                pieChartData.set(2, new PieChart.Data("Abort", ExecuteTest.noOfAborted));
+                                passData.setPieValue(1);
+                                failData.setPieValue(0);
+                                abortData.setPieValue(0);
+                                noResultData.setPieValue(0);
+                                summaryChart.getStylesheets().add(getClass().getResource("test.css").toExternalForm());
+                                summaryChart.setData(pieChartData);
+                            } catch (Exception e) {
+                                e.printStackTrace();
+                            }
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        }
+                    }
+                };
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void updateData(String line) {
+
+        casePatt = Pattern.compile("\\s*Result\\s+summary\\s+for\\s+Testcase(\\d+)");
+        m = casePatt.matcher(line);
+        if (m.find()) {
+            Date dNow = new Date();
+            SimpleDateFormat ft = new SimpleDateFormat("hh:mm:ss a zzz dd.MM.yyyy");
+            testCaseStartTime = ft.format(dNow);
+            currentTestCase = m.group(1);
+            stepHash.clear();
+            getTestSteps(m.group(1));
+            Image image = new Image(getClass().getResourceAsStream("/images/loading.gif"), 10, 10, true, true);
+            Label statusImage = new Label("", new ImageView(image));
+            stepSummaryData = FXCollections.observableArrayList(new StepTable(new Label(""), new Label(""), new Label("")));
+            Iterator entries = stepHash.entrySet().iterator();
+            while (entries.hasNext()) {
+                Map.Entry entry = (Map.Entry) entries.next();
+                String key = (String) entry.getKey();
+                String value = (String) entry.getValue();
+                stepSummaryData.add(new StepTable(new Label(key), new Label(value), new Label("", new ImageView(image))));
+            }
+            stepTable.setItems(stepSummaryData);
+        }
+
+        namePatt = Pattern.compile("\\[(.*)\\]\\s*\\[(.*)\\]\\s*\\[\\s*CASE\\s*\\](.*)\\s*");
+        m = namePatt.matcher(line);
+
+        if (m.find()) {
+            testCaseName = m.group(3);
+            Image image = new Image(getClass().getResourceAsStream("/images/progress.png"));
+            statusImage = new Label("", new ImageView(image));
+            if (tableIndex < 0) {
+                data = FXCollections.observableArrayList(new SummaryTable(new Label(currentTestCase), new Label(testCaseName),
+                        statusImage, new Label(testCaseStartTime), new Label()));
+            } else {
+                data.add(new SummaryTable(new Label(currentTestCase), new Label(testCaseName), statusImage,
+                        new Label(testCaseStartTime), new Label("")));
+            }
+            tableIndex++;
+        }
+
+        stepPatt = Pattern.compile("\\[(.*)\\]\\s*\\[(.*)\\]\\s*\\[\\s*STEP\\s*\\]\\s*(\\d+)\\.(\\d+):(.*)\\s*");
+
+        m = stepPatt.matcher(line);
+        if (m.find()) {
+            String currentStepNumber = m.group(3) + "." + m.group(4);
+            for (int i = 1; i < stepSummaryData.size(); i++) {
+                if (stepSummaryData.get(i).getTestStepId().getText().equals(currentStepNumber)) {
+                    Image image = new Image(getClass().getResourceAsStream("/images/progress.png"));
+                    stepTableIndex = i;
+                    stepSummaryData.set(i, new StepTable(new Label(stepSummaryData.get(i).getTestStepId().getText()), new Label(stepSummaryData.get(i).getTestStepName().getText()), new Label("", new ImageView(image))));
+                    Image images = new Image(getClass().getResourceAsStream("/images/Pass_Icon.png"));
+                }
+            }
+
+        }
+
+        assertionPatt = Pattern.compile("\\s*(.*)\\s*-\\s*(\\w+)\\s*-\\s*(\\w+)\\s*-\\s*(.*)\\s*");
+        m = assertionPatt.matcher(line);
+        if (m.find() && stepTableIndex > -1) {
+            if (m.group(3).equals("INFO") && m.group(4).equals("Assertion Passed")) {
+                Image image = new Image(getClass().getResourceAsStream("/images/Pass_Icon.png"));
+                stepSummaryData.set(stepTableIndex, new StepTable(new Label(stepSummaryData.get(stepTableIndex).getTestStepId().getText()),
+                        new Label(stepSummaryData.get(stepTableIndex).getTestStepName().getText()), new Label("", new ImageView(image))));
+            } else if (m.group(3).equals("WARNING") && m.group(4).equals("Assertion Failed")) {
+                Image image = new Image(getClass().getResourceAsStream("/images/Fail_Icon.png"));
+                stepSummaryData.set(stepTableIndex, new StepTable(new Label(stepSummaryData.get(stepTableIndex).getTestStepId().getText()),
+                        new Label(stepSummaryData.get(stepTableIndex).getTestStepName().getText()), new Label("", new ImageView(image))));
+                XmlRpcClient server;
+            }
+
+        }
+
+        resultPatt = Pattern.compile("\\s*Result:\\s+(\\w+)\\s*");
+        m = resultPatt.matcher(line);
+        if (m.find()) {
+            testCaseStatus = m.group(1);
+            Date dNow = new Date();
+            Image image;
+            SimpleDateFormat ft = new SimpleDateFormat("hh:mm:ss a zzz dd.MM.yyyy");
+            testCaseEndTime = ft.format(dNow);
+            if (testCaseStatus.equalsIgnoreCase("No result")) {
+                image = new Image(getClass().getResourceAsStream("/images/noResult.png"));
+                statusImage = new Label("", new ImageView(image));;
+                ExecuteTest.noOfNoResult++;
+            }
+
+            if (testCaseStatus.equalsIgnoreCase("Pass")) {
+                image = new Image(getClass().getResourceAsStream("/images/Pass_Icon.png"));
+                statusImage = new Label("", new ImageView(image));
+                ExecuteTest.noOfPassed++;
+            }
+            if (testCaseStatus.equals("Failed")) {
+                image = new Image(getClass().getResourceAsStream("/images/Fail_Icon.png"));
+                statusImage = new Label("", new ImageView(image));
+                ExecuteTest.noOfFailed++;
+            } else if (testCaseStatus.equals("Aborted")) {
+                image = new Image(getClass().getResourceAsStream("/images/Abort_Icon.png"));
+                statusImage = new Label("", new ImageView(image));
+                this.noOfAborted++;
+            }
+            data.set(tableIndex, new SummaryTable(new Label(currentTestCase), new Label(testCaseName),
+                    statusImage, new Label(testCaseStartTime), new Label(testCaseEndTime)));
+            summaryTable.setItems(data);
+        }
+
+        summaryPatt = Pattern.compile("\\s*Test+\\s+Execution(.*)");
+        m = summaryPatt.matcher(line);
+        if (m.find()) {
+        }
+
+        testStartPatt = Pattern.compile("Test\\s+Start\\s+\\:\\s+(.*)");
+        m = testStartPatt.matcher(line);
+        if (m.find()) {
+            Image image = new Image(getClass().getResourceAsStream("/images/Pass_Icon.png"));
+            statusImage = new Label("", new ImageView(image));
+            data.set(tableIndex, new SummaryTable(new Label(currentTestCase), new Label(testCaseName),
+                    statusImage, new Label(testCaseStartTime), new Label(testCaseEndTime)));
+            stepTable.setVisible(false);
+            finalSummaryTable.setVisible(true);
+            summaryChart.setVisible(true);
+            finalSummaryData = FXCollections.observableArrayList(new FinalSummaryTable(new Label(""), new Label("")));
+            finalSummaryTable.setItems(finalSummaryData);
+            testStart = m.group(1);
+            finalSummaryData.set(0, new FinalSummaryTable(new Label("Test Start"), new Label(testStart)));
+            finalSummaryTable.setItems(finalSummaryData);
+        }
+        testEndPatt = Pattern.compile("Test\\s+End\\s+\\:\\s+(.*)");
+        m = testEndPatt.matcher(line);
+        if (m.find()) {
+            testEnd = m.group(1);
+            finalSummaryData.add(new FinalSummaryTable(new Label("Test End"), new Label(testEnd)));
+            finalSummaryTable.setItems(finalSummaryData);
+        }
+        testExecutionTimePatt = Pattern.compile("\\s*Execution\\s+Time\\s+\\:\\s+(.*)");
+        m = testExecutionTimePatt.matcher(line);
+        if (m.find()) {
+            testExecutionTime = m.group(1);
+            finalSummaryData.add(new FinalSummaryTable(new Label("Execution Time"), new Label(testExecutionTime)));
+            finalSummaryTable.setItems(finalSummaryData);
+        }
+        testsPlannedPatt = Pattern.compile("\\s*Total\\s+tests\\s+planned\\s+\\:\\s*(.*)");
+        m = testsPlannedPatt.matcher(line);
+        if (m.find()) {
+            testsPlanned = m.group(1);
+            finalSummaryData.add(new FinalSummaryTable(new Label("Total Tests Planned"), new Label(testsPlanned)));
+            finalSummaryTable.setItems(finalSummaryData);
+        }
+
+        testsRunPatt = Pattern.compile("\\s*Total\\s+tests\\s+Run\\s+\\:\\s+(.*)");
+        m = testsRunPatt.matcher(line);
+        if (m.find()) {
+            testsRun = m.group(1);
+            finalSummaryData.add(new FinalSummaryTable(new Label("Total Tests Run"), new Label(testsRun)));
+            finalSummaryTable.setItems(finalSummaryData);
+        }
+        totalPassPatt = Pattern.compile("Total\\s+Pass\\s+\\:\\s+(.*)");
+        m = totalPassPatt.matcher(line);
+        if (m.find()) {
+            totalPass = m.group(1);
+            Label totalPassL = new Label("Total Pass");
+            totalPassL.setTextFill(Color.GREEN);
+            totalPassL.setStyle("-fx-font-weight: bold");
+            Label totalPassValue = new Label(totalPass);
+            totalPassValue.setTextFill(Color.GREEN);
+            totalPassValue.setStyle("-fx-font-weight: bold");
+            finalSummaryData.add(new FinalSummaryTable(totalPassL, totalPassValue));
+            finalSummaryTable.setItems(finalSummaryData);
+        }
+        totalFailPatt = Pattern.compile("Total\\s+Fail\\s+\\:\\s+(.*)");
+        m = totalFailPatt.matcher(line);
+        if (m.find()) {
+            totalFail = m.group(1);
+            Label totalFailL = new Label("Total Fail");
+            totalFailL.setTextFill(Color.RED);
+            totalFailL.setStyle("-fx-font-weight: bold");
+            Label totalFailValue = new Label(totalFail);
+            totalFailValue.setTextFill(Color.RED);
+            totalFailValue.setStyle("-fx-font-weight: bold");
+            finalSummaryData.add(new FinalSummaryTable(totalFailL, totalFailValue));
+            finalSummaryTable.setItems(finalSummaryData);
+        }
+
+        totalreRun = Pattern.compile("Total\\s+Re\\-Run\\s+\\:\\s+(.*)");
+        m = totalreRun.matcher(line);
+        if (m.find()) {
+            Label totalReRun = new Label("Total Re-Run");
+            totalReRun.setTextFill(Color.BLUE);
+            totalReRun.setStyle("-fx-font-weight: bold");
+            Label totalReRunValue = new Label(m.group(1));
+            totalReRunValue.setTextFill(Color.BLUE);
+            totalReRunValue.setStyle("-fx-font-weight: bold");
+            finalSummaryData.add(new FinalSummaryTable(totalReRun, totalReRunValue));
+            finalSummaryTable.setItems(finalSummaryData);
+        }
+
+        noResultPatt = Pattern.compile("Total\\s+No\\s+Result\\s+\\:\\s+(.*)");
+        m = noResultPatt.matcher(line);
+        if (m.find()) {
+            noResult = m.group(1);
+            finalSummaryData.add(new FinalSummaryTable(new Label("Total No-Result"), new Label(noResult)));
+            finalSummaryTable.setItems(finalSummaryData);
+        }
+
+        totalAbortPatt = Pattern.compile("Total\\sabort\\s+\\:\\s+(.*)");
+        m = totalAbortPatt.matcher(line);
+        if (m.find()) {
+            totalAbort = m.group(1);
+            finalSummaryData.add(new FinalSummaryTable(new Label("Total Abort"), new Label(totalAbort)));
+            finalSummaryTable.setItems(finalSummaryData);
+        }
+        execPercentagePatt = Pattern.compile("Execution\\s+Result\\s+\\:\\s+(.*)");
+        m = execPercentagePatt.matcher(line);
+        if (m.find()) {
+            execPercentage = m.group(1);
+            finalSummaryData.add(new FinalSummaryTable(new Label("Execution Percentage"), new Label(execPercentage)));
+            finalSummaryTable.setItems(finalSummaryData);
+            Platform.runLater(r3);
+        }
+        successPercentagePatt = Pattern.compile("Success\\s+Percentage\\s+\\:\\s+(.*)");
+        m = successPercentagePatt.matcher(line);
+        if (m.find()) {
+            successPercentage = m.group(1);
+            finalSummaryData.add(new FinalSummaryTable(new Label("Success Percentage"), new Label(successPercentage)));
+            finalSummaryTable.setItems(finalSummaryData);
+        }
+    }
+
+    public ExecuteTest() {
+    }
+
+    public String getTestCase() {
+        return currentTestCase;
+    }
+
+    public void getTestSteps(String caseNumber) {
+        OFAFileOperations fileOperation = new OFAFileOperations();
+        int stepCount = 0;
+        String stepCounter = "";
+        String ospkFileName = label.hierarchyTestON + "/tests/" + selectedTest + "/" + selectedTest + ".ospk";
+        String pythonScriptName = label.hierarchyTestON + "/tests/" + selectedTest + "/" + selectedTest + ".py";
+        BufferedReader input = null;
+        ArrayList<String> contents = new ArrayList<String>();
+        File scriptName = new File(ospkFileName);
+        if (scriptName.exists()) {
+            try {
+                //use buffering, reading one line at a time
+                //FileReader always assumes default encoding is OK!
+                try {
+                    input = new BufferedReader(new FileReader(scriptName));
+                } catch (Exception e) {
+                }
+
+                try {
+                    String line = null; //not declared within while loop
+                    while ((line = input.readLine()) != null) {
+                        contents.add(line);
+                    }
+                } finally {
+                    try {
+                        input.close();
+                    } catch (Exception e) {
+                    }
+                }
+            } catch (IOException ex) {
+                ex.printStackTrace();
+            }
+            for (int i = 0; i < contents.size(); i++) {
+                Pattern casePattern = Pattern.compile("\\s*CASE\\s*(\\d+)\\s*");
+                Matcher caseMatcher = casePattern.matcher(contents.get(i));
+                if (caseMatcher.find()) {
+                    if (caseMatcher.group(1).equals(caseNumber)) {
+                        i++;
+                        Pattern casePatterns = Pattern.compile("\\s*CASE\\s*(\\d+)\\s*");
+                        Matcher caseMatchers = casePatterns.matcher(contents.get(i));
+                        while (!caseMatchers.find() && i < contents.size()) {
+                            Pattern casesPatterns = Pattern.compile("\\s*CASE\\s*(\\d+)\\s*");
+                            Matcher casesMatchers = casesPatterns.matcher(contents.get(i));
+                            if (casesMatchers.find()) {
+                                break;
+                            } else {
+                                Pattern stepPattern = Pattern.compile("\\s*STEP\\s+\"\\s*(.*)\\s*\"\\s*");
+                                Matcher stepMatcher = stepPattern.matcher(contents.get(i));
+                                try {
+                                    if (stepMatcher.find()) {
+                                        stepCount++;
+                                        stepCounter = caseNumber + "." + String.valueOf(stepCount);
+                                        stepHash.put(stepCounter, stepMatcher.group(1));
+                                    }
+                                } catch (Exception e) {
+                                    break;
+                                }
+                                i++;
+                            }
+
+                        }
+                        i--;
+                    }
+
+                }
+            }
+        } else {
+            try {
+                //use buffering, reading one line at a time
+                //FileReader always assumes default encoding is OK!
+                try {
+                    input = new BufferedReader(new FileReader(pythonScriptName));
+
+                } catch (Exception e) {
+                }
+
+                try {
+                    String line = null; //not declared within while loop
+
+                    while ((line = input.readLine()) != null) {
+                        contents.add(line);
+                    }
+                } finally {
+                    try {
+                        input.close();
+                    } catch (Exception e) {
+                    }
+
+                }
+            } catch (IOException ex) {
+                ex.printStackTrace();
+            }
+
+            for (int i = 0; i < contents.size(); i++) {
+                Pattern casePattern = Pattern.compile("\\s*def\\s+CASE(\\d+)\\s*\\(\\s*(.*)\\s*\\)\\s*:\\s*");
+                Matcher caseMatcher = casePattern.matcher(contents.get(i));
+                if (caseMatcher.find()) {
+                    if (caseMatcher.group(1).equals(caseNumber)) {
+                        i++;
+                        Pattern casePatterns = Pattern.compile("\\s*def\\s+CASE(\\d+)\\s*\\(\\s*(.*)\\s*\\)\\s*:\\s*");
+                        Matcher caseMatchers = casePatterns.matcher(contents.get(i));
+                        while (!caseMatchers.find() && i < contents.size()) {
+                            Pattern casesPatterns = Pattern.compile("\\s*def\\s+CASE(\\d+)\\s*\\(\\s*(.*)\\s*\\)\\s*:\\s*");
+                            Matcher casesMatchers = casesPatterns.matcher(contents.get(i));
+                            if (casesMatchers.find()) {
+                                break;
+                            } else {
+                                Pattern stepPattern = Pattern.compile("\\s*main.step\\(\\s*\"\\s*(.*)\\s*\"\\s*\\)\\s*");
+                                Matcher stepMatcher = stepPattern.matcher(contents.get(i));
+                                try {
+                                    if (stepMatcher.find()) {
+                                        stepCount++;
+                                        stepCounter = caseNumber + "." + String.valueOf(stepCount);
+                                        stepHash.put(stepCounter, stepMatcher.group(1));
+                                    }
+                                } catch (Exception e) {
+                                    break;
+                                }
+                                i++;
+                            }
+                        }
+                        i--;
+                    }
+                }
+            }
+        }
+    }
+
+    public void getCaseName() {
+        int stepCount = 0;
+        String stepCounter = "";
+        String paramFilePath = label.hierarchyTestON + "/tests/" + selectedTest + "/" + selectedTest + ".params";
+        FileInputStream fstream;
+        String testCases = "";
+        ArrayList<String> paramFileName = new ArrayList<String>();
+        ArrayList<String> nameBetweenTags = new ArrayList<String>();
+        try {
+            fstream = new FileInputStream(paramFilePath);
+            DataInputStream in = new DataInputStream(fstream);
+            BufferedReader br = new BufferedReader(new InputStreamReader(in));
+            String strLine;
+            try {
+                while ((strLine = br.readLine()) != null) {
+                    paramFileName.add(strLine);
+                }
+            } catch (IOException ex) {
+                Logger.getLogger(ExecuteTest.class.getName()).log(Level.SEVERE, null, ex);
+            }
+        } catch (FileNotFoundException ex) {
+            Logger.getLogger(ExecuteTest.class.getName()).log(Level.SEVERE, null, ex);
+        }
+
+        for (int index = 0; index < paramFileName.size(); index++) {
+            Pattern testsPattern = Pattern.compile("<testcases>\\s*(.*)\\s*</testcases>");
+            Matcher testMatcher = testsPattern.matcher(paramFileName.get(index));
+            if (testMatcher.find()) {
+                testCases = testMatcher.group(1);
+                testCases = testCases.replaceAll(" ", "");
+            }
+
+        }
+
+        String[] testArray = null;
+        testArray = testCases.split(",");
+        String ospkFileName = label.hierarchyTestON + "/tests/" + selectedTest + "/" + selectedTest + ".ospk";
+        String pythonScriptName = label.hierarchyTestON + "/tests/" + selectedTest + "/" + selectedTest + ".py";
+        BufferedReader input = null;
+        ArrayList<String> contents = new ArrayList<String>();
+        File scriptName = new File(ospkFileName);
+        String caseId = "";
+        String caseName = "";
+        if (scriptName.exists()) {
+            try {
+                FileInputStream fstream1 = new FileInputStream(ospkFileName);
+                ArrayList<String> driverFunctionName = new ArrayList<String>();
+                DataInputStream in = new DataInputStream(fstream1);
+                BufferedReader br = new BufferedReader(new InputStreamReader(in));
+                String strLine;
+                while ((strLine = br.readLine()) != null) {
+                    Pattern casePattern = Pattern.compile("^CASE\\s+(\\d+)");
+                    Matcher match = casePattern.matcher(strLine);
+                    while (match.find()) {
+                        driverFunctionName.add(match.group());
+                        caseId = match.group(1);
+                        strLine = br.readLine();
+                        casePattern = Pattern.compile("NAME\\s+(\\\"+(.*)\\\")");
+                        match = casePattern.matcher(strLine);
+                        if (match.find()) {
+                            caseName = match.group(2);
+                        }
+                        caseNameHash.put(caseId, caseName);
+                    }
+                }
+            } catch (Exception e) {
+            }
+        } else {
+            try {
+
+                FileInputStream fstream2 = new FileInputStream(pythonScriptName);
+                ArrayList<String> driverFunctionName = new ArrayList<String>();
+                DataInputStream in = new DataInputStream(fstream2);
+                BufferedReader br = new BufferedReader(new InputStreamReader(in));
+                String strLine;
+                while ((strLine = br.readLine()) != null) {
+                    Pattern casePattern = Pattern.compile("\\s*def\\s+CASE(\\d+)\\s*\\(\\s*(.*)\\s*\\)\\s*:\\s*");
+                    Matcher match = casePattern.matcher(strLine);
+                    if (match.find()) {
+                        driverFunctionName.add(match.group());
+                        if (Arrays.asList(testArray).contains(match.group(1))) {
+                            caseId = match.group(1);
+                        } else {
+                            caseId = null;
+                        }
+                        strLine = br.readLine();
+                    }
+
+                    casePattern = Pattern.compile("\\s*main.case\\(\\s*\"\\s*(.*)\\s*\"\\s*\\)\\s*");
+                    match = casePattern.matcher(strLine);
+
+                    if (match.find()) {
+                        caseName = match.group(1);
+                        if (caseId != null) {
+                            caseNameHash.put(caseId, caseName);
+                        }
+                    }
+                }
+            } catch (Exception e) {
+            }
+        }
+    }
+}
diff --git a/TestON/TAI/src/tai_ofa/ExecutionConsole.java b/TestON/TAI/src/tai_ofa/ExecutionConsole.java
new file mode 100644
index 0000000..b88d586
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/ExecutionConsole.java
@@ -0,0 +1,98 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package tai_ofa;
+
+import javafx.application.Application;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.Group;
+import javafx.scene.Scene;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.control.Tab;
+import javafx.scene.control.TabPane;
+import javafx.scene.control.TextField;
+import javafx.scene.control.TextFieldBuilder;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.StackPane;
+import javafx.scene.layout.VBox;
+import javafx.stage.Stage;
+
+/**
+ *
+ * @author Raghav Kashyap raghavkashyap@paxterrasolutions.com
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+ */
+public class ExecutionConsole extends Application {
+    
+    Stage copyStage;
+    Scene scene;
+    TextField value ;
+    String Title,enteredValue ;
+    Button submit ;
+    ExecutionConsole(String Title,Button enter, TextField value) {
+        this.Title = Title;
+        this.submit = enter;
+        this.value = value;
+    }
+   
+  @Override public void start(final Stage primaryStage) throws Exception {
+    copyStage = primaryStage;
+    
+    Group root = new Group();
+    GridPane basePane = new GridPane(); 
+    basePane.setPadding(new Insets(2, 0, 2, 0));
+    basePane.setVgap(5);
+    basePane.setHgap(2);
+    value.setEditable(true);
+    value.clear();
+    enteredValue = "";
+    Label info = new Label("Please pass the appropriate value");
+    
+    
+    basePane.add(value, 0, 1);
+    basePane.add(submit, 1, 1);
+    basePane.add(info, 0, 0);
+    scene = new Scene(root, 550, 60);
+    
+    root.getChildren().addAll(basePane);
+    primaryStage.setTitle(Title);  
+    primaryStage.setScene(scene);
+    primaryStage.show();
+  }
+  
+  public void closeWindow(){
+      copyStage.close();
+  }
+  public void setValue(String value){
+      enteredValue = value;
+  }
+  public String getValue(){
+      return enteredValue;
+  }
+
+  public void setTitles(String title){
+      copyStage.setTitle(title);
+  }
+  
+}
diff --git a/TestON/TAI/src/tai_ofa/FinalSummaryTable.java b/TestON/TAI/src/tai_ofa/FinalSummaryTable.java
new file mode 100644
index 0000000..5ed908b
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/FinalSummaryTable.java
@@ -0,0 +1,57 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package tai_ofa;
+
+import javafx.scene.control.Label;
+
+/**
+ *
+ * @author Raghav Kashyap raghavkashyap@paxterrasolutions.com
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+ */
+
+public class FinalSummaryTable {
+    public Label summaryItem;
+    public Label information;
+    
+    public FinalSummaryTable() {
+        
+    }
+    public FinalSummaryTable(Label summaryItem, Label information) {
+        
+        this.summaryItem = summaryItem;
+        this.information = information;
+        
+    }
+    
+  
+     public Label getSummaryItem() {
+        return  summaryItem;
+    }
+    public void setSummaryItem(Label newSummaryItem) {
+        summaryItem = newSummaryItem;
+    }
+    public Label getInformation() {
+        return  information;
+    }
+    public void setInformation(Label newInformation) {
+        information = newInformation;
+    }
+    
+}
+
diff --git a/TestON/TAI/src/tai_ofa/LoadDirectory.java b/TestON/TAI/src/tai_ofa/LoadDirectory.java
new file mode 100644
index 0000000..25eb317
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/LoadDirectory.java
@@ -0,0 +1,204 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package tai_ofa;
+
+import java.io.File;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.attribute.BasicFileAttributes;
+import javafx.event.Event;
+import javafx.event.EventHandler;
+import javafx.scene.Node;
+import javafx.scene.control.TreeItem;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+
+/**
+ *
+ * @author Raghav Kashyap (raghavkashyap@paxterrasolutions.com)
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+ */
+public class LoadDirectory extends TreeItem<String> {
+
+    //this stores the full path to the file or directory
+    OFAFileOperations fileOperation = new OFAFileOperations();
+    private String fullPath;
+
+    public String getFullPath() {
+        return (this.fullPath);
+    }
+    private boolean isDirectory;
+
+    public boolean isDirectory() {
+        return (this.isDirectory);
+    }
+
+    public LoadDirectory(Path file) {
+        super(file.toString());
+        this.fullPath = file.toString();
+
+        if (Files.isDirectory(file)) {
+            this.isDirectory = true;
+
+            if ("common".equals(file.getFileName().toString())) {
+                Node rootIcon = new ImageView(new Image(getClass().getResourceAsStream("/images/project.jpeg"), 20, 20, true, true));
+                rootIcon.setId("/images/project.jpeg");
+                this.setGraphic(rootIcon);
+            } else if ("cli".equalsIgnoreCase(file.getFileName().toString())) {
+                Node rootIcon2 = new ImageView(new Image(getClass().getResourceAsStream("/images/terminal.png"), 20, 20, true, true));
+                rootIcon2.setId("/images/terminal.png");
+                this.setGraphic(rootIcon2);
+            } else if ("api".equals(file.getFileName().toString())) {
+                Node rootIcon3 = new ImageView(new Image(getClass().getResourceAsStream("/images/api.jpg"), 20, 20, true, true));
+                rootIcon3.setId("/images/api.jpg");
+                this.setGraphic(rootIcon3);
+            } else if ("tool".equals(file.getFileName().toString())) {
+                Node rootIcon4 = new ImageView(new Image(getClass().getResourceAsStream("/images/tool.jpg"), 20, 20, true, true));
+                this.setGraphic(rootIcon4);
+            } else if ("remotesys".equals(file.getFileName().toString())) {
+                Node rootIcon5 = new ImageView(new Image(getClass().getResourceAsStream("/images/automatorui.png"), 20, 20, true, true));
+                this.setGraphic(rootIcon5);
+            } else if ("emulator".equals(file.getFileName().toString())) {
+                Node rootIcon6 = new ImageView(new Image(getClass().getResourceAsStream("/images/emulator.jpg"), 20, 20, true, true));
+                this.setGraphic(rootIcon6);
+            } else if ("controller".equals(file.getFileName().toString())) {
+                Node rootIcon6 = new ImageView(new Image(getClass().getResourceAsStream("/images/controller.jpg"), 20, 20, true, true));
+                this.setGraphic(rootIcon6);
+            } else if ("remotetestbed".equals(file.getFileName().toString())) {
+                Node rootIcon5 = new ImageView(new Image(getClass().getResourceAsStream("/images/testbed.jpg"), 20, 20, true, true));
+                this.setGraphic(rootIcon5);
+            }
+
+        } else {
+            this.isDirectory = false;
+            String fileName = file.getFileName().toString();
+            String ext = fileOperation.getExtension(fileName);
+            if (".py".equals(ext)) {
+                if ("fvtapidriver.py".equalsIgnoreCase(fileName)) {
+                    Node rootIcon7 = new ImageView(new Image(getClass().getResourceAsStream("/images/flowvisor.png"), 20, 20, true, true));
+                    rootIcon7.setId("/images/flowvisor.png");
+                    this.setGraphic(rootIcon7);
+                } else if ("mininetclidriver.py".equalsIgnoreCase(fileName)) {
+                    Node rootIcon8 = new ImageView(new Image(getClass().getResourceAsStream("/images/mininet.jpg"), 20, 20, true, true));
+                    rootIcon8.setId("/images/mininet.jpg");
+                    this.setGraphic(rootIcon8);
+                } else if ("poxclidriver.py".equalsIgnoreCase(fileName)) {
+                    Node rootIcon9 = new ImageView(new Image(getClass().getResourceAsStream("/images/pox.jpg"), 20, 20, true, true));
+                    rootIcon9.setId("/images/pox.jpg");
+                    this.setGraphic(rootIcon9);
+                } else if ("dpctlclidriver.py".equals(fileName)) {
+                    Node rootIcon10 = new ImageView(new Image(getClass().getResourceAsStream("/images/dpctl.jpg"), 20, 20, true, true));
+                    rootIcon10.setId("/images/dpctl.jpg");
+                    this.setGraphic(rootIcon10);
+                } else if ("hpswitchclidriver.py".equalsIgnoreCase(fileName)) {
+                    Node rootIcon11 = new ImageView(new Image(getClass().getResourceAsStream("/images/hp.jpg"), 20, 20, true, true));
+                    rootIcon11.setId("/images/hp.jpg");
+                    this.setGraphic(rootIcon11);
+                } else if ("cisco.py".equalsIgnoreCase(fileName)) {
+                    Node rootIcon12 = new ImageView(new Image(getClass().getResourceAsStream("/images/Cisco.png"), 20, 20, true, true));
+                    rootIcon12.setId("/images/Cisco.png");
+                    this.setGraphic(rootIcon12);
+                } else if ("flowvisorclidriver.py".equalsIgnoreCase(fileName)) {
+                    Node rootIcon12 = new ImageView(new Image(getClass().getResourceAsStream("/images/flowvisor.png"), 20, 20, true, true));
+                    rootIcon12.setId("/images/flowvisor.png");
+                    this.setGraphic(rootIcon12);
+                } else if ("floodlightclidriver.py".equalsIgnoreCase(fileName)) {
+                    Node rootIcon11 = new ImageView(new Image(getClass().getResourceAsStream("/images/floodlight.jpg"), 20, 20, true, true));
+                    rootIcon11.setId("/images/floodlight.jpg");
+                    this.setGraphic(rootIcon11);
+                } else if ("remotevmdriver.py".equalsIgnoreCase(fileName)) {
+                    Node rootIcon11 = new ImageView(new Image(getClass().getResourceAsStream("/images/remotevm.jpg"), 20, 20, true, true));
+                    rootIcon11.setId("/images/remotevm.jpg");
+                    this.setGraphic(rootIcon11);
+                } else if ("remotepoxdriver.py".equalsIgnoreCase(fileName)) {
+                    Node rootIcon11 = new ImageView(new Image(getClass().getResourceAsStream("/images/pox.jpg"), 20, 20, true, true));
+                    rootIcon11.setId("/images/pox.jpg");
+                    this.setGraphic(rootIcon11);
+                } else if ("flowvisordriver.py".equalsIgnoreCase(fileName)) {
+                    Node rootIcon11 = new ImageView(new Image(getClass().getResourceAsStream("/images/flowvisor.png"), 20, 20, true, true));
+                    rootIcon11.setId("/images/flowvisor.png");
+                    this.setGraphic(rootIcon11);
+                } else if ("switchclidriver.py".equalsIgnoreCase(fileName)) {
+                    Node rootIcon11 = new ImageView(new Image(getClass().getResourceAsStream("/images/switchVM.png"), 20, 20, true, true));
+                    rootIcon11.setId("/images/switchVM.png");
+                    this.setGraphic(rootIcon11);
+                } else {
+                    Node rootIcon6 = new ImageView(new Image(getClass().getResourceAsStream("/images/defaultTerminal.png"), 20, 20, true, true));
+                    rootIcon6.setId("/images/defaultTerminal.png");
+                    this.setGraphic(rootIcon6);
+                }
+            }
+            //if you want different icons for different file types this is where you'd do it
+        }
+        if (!fullPath.endsWith(File.separator)) {
+            String finalValue = null;
+            String value = file.getFileName().toString();
+            String ext = fileOperation.getExtension(value);
+            if (ext == null) {
+                this.setValue(value);
+            } else {
+                if (ext.equals(".py")) {
+                    finalValue = value.replace(ext, "");
+                }
+                this.setValue(finalValue);
+            }
+
+        }
+        this.addEventHandler(TreeItem.branchExpandedEvent(), new EventHandler() {
+            @Override
+            public void handle(Event e) {
+                LoadDirectory source = (LoadDirectory) e.getSource();
+                if (source.isDirectory() && source.isExpanded()) {
+                }
+                try {
+                    if (source.getChildren().isEmpty()) {
+                        Path path = Paths.get(source.getFullPath());
+                        BasicFileAttributes attribs = Files.readAttributes(path, BasicFileAttributes.class);
+                        if (attribs.isDirectory()) {
+                            DirectoryStream<Path> dir = Files.newDirectoryStream(path);
+                            for (Path file : dir) {
+                                LoadDirectory treeNode = new LoadDirectory(file);
+                                if (treeNode.getValue() != null && !treeNode.getValue().equals("__init__") && !treeNode.getValue().equals("controllerdriver") && !treeNode.getValue().equals("apidriver")
+                                        && !treeNode.getValue().equals("clidriver") && !treeNode.getValue().equals("controllerdriver") && !treeNode.getValue().equals("emulatordriver") && !treeNode.getValue().equals("toolsdriver") && !treeNode.getValue().equals("remotesysdriver")) //source.getChildren().add(treeNode);
+                                {
+                                    source.getChildren().add(treeNode);
+                                }
+                                treeNode.setExpanded(true);
+                            }
+                        }
+                    }
+
+                } catch (Exception ex) {
+                }
+            }
+        });
+        this.addEventHandler(TreeItem.branchCollapsedEvent(), new EventHandler() {
+            @Override
+            public void handle(Event e) {
+                LoadDirectory source = (LoadDirectory) e.getSource();
+                if (source.isDirectory() && !source.isExpanded()) {
+                    ImageView iv = (ImageView) source.getGraphic();
+                }
+            }
+        });
+
+
+    }
+}
diff --git a/TestON/TAI/src/tai_ofa/OFAAnchorInsideImageNode.java b/TestON/TAI/src/tai_ofa/OFAAnchorInsideImageNode.java
new file mode 100644
index 0000000..1cb382b
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/OFAAnchorInsideImageNode.java
@@ -0,0 +1,347 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package tai_ofa;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import javafx.beans.property.DoubleProperty;
+import javafx.collections.ObservableList;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.scene.Cursor;
+import javafx.scene.Node;
+import javafx.scene.control.Button;
+import javafx.scene.input.MouseButton;
+import javafx.scene.input.MouseDragEvent;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.Pane;
+import javafx.scene.layout.VBox;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Circle;
+import javafx.scene.shape.Line;
+import javafx.scene.shape.StrokeLineCap;
+import javafx.stage.Stage;
+
+/**
+ *
+ * @author Raghav Kashyap (raghavkashyap@paxterrasolutions.com)
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+ */
+class OFAAnchorInsideImageNode {
+
+    Double increaseBindX;
+    Double increaseBindY;
+    /*Double addX and addY is passed as an argument as binding coordinates are different for Wizard
+     and toplogyNode(In the editor)*/
+
+    public OFAAnchorInsideImageNode(Double addX, Double addY) {
+        increaseBindX = addX;
+        increaseBindY = addY;
+    }
+    boolean anchorFlag = false;
+    OFATopologyLink topologyLink = new OFATopologyLink();
+    ArrayList<HashMap<String, String>> arrayOfLinkTopologyHash = new ArrayList<HashMap<String, String>>();
+
+    public void anchorsInsideImage(final TopologyWizard.Anchor anchor, final double bindLineStartx, final double bindLineStarty, final double bindLineEndx, final double bindLineEndy, final Pane hb, final DraggableNode content,
+            final VBox hbox, final Line con, final ArrayList<String> draggedImagesName, final ArrayList<HashMap<String, String>> arrayOfInterFaceHash, final HashMap<String, String> linkTopologyHash, final HashMap<Node, String> anchorNodeHash) {
+        final Line con11 = new Line();
+
+        anchor.setOnDragDetected(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent arg0) {
+                anchor.startFullDrag();
+                enableDrag(anchor);
+            }
+        });
+
+        anchor.setOnMouseDragReleased(new EventHandler<MouseDragEvent>() {
+            @Override
+            public void handle(MouseDragEvent arg0) {
+                ObservableList<Node> allNodesCanvas = hb.getChildren();
+                boolean flag = false;
+                String startNode = null;
+                String endNode = null;
+                try {
+                    for (Node node : allNodesCanvas) {
+                        Double x = node.getLayoutX() + increaseBindX;
+                        Double y = node.getLayoutY() + increaseBindY;
+                        if (node.toString().startsWith("DraggableNode")) {
+                            for (int i = 0; i <= 80; i++) {
+                                for (int j = 0; j <= 100; j++) {
+                                    Double x1 = node.getLayoutX() + increaseBindX;
+                                    Double y1 = node.getLayoutY() + increaseBindY;
+                                    Double x11 = x1 + i;
+                                    Double y11 = y1 + j;
+                                    if (x11 == arg0.getSceneX()) {
+                                        if (y11 == arg0.getSceneY()) {
+                                            con11.setStrokeLineCap(StrokeLineCap.ROUND);
+                                            con11.setStroke(Color.MIDNIGHTBLUE);
+                                            con11.setStrokeWidth(2.0);
+                                            con11.startXProperty().bind(content.layoutXProperty().add(bindLineStartx));
+                                            con11.startYProperty().bind(content.layoutYProperty().add(bindLineStarty));
+                                            startNode = ((Integer) content.hashCode()).toString();
+                                            con11.endXProperty().bind(node.layoutXProperty().add(bindLineEndx));
+                                            con11.endYProperty().bind(node.layoutYProperty().add(bindLineEndy));
+                                            endNode = ((Integer) node.hashCode()).toString();
+                                            con11.setId(startNode + "," + endNode);
+                                            hbox.setStyle("-fx-border-color: Transparent");
+                                            con.setVisible(false);
+                                            anchor.setVisible(false);
+                                            hb.getChildren().add(con11);
+                                            flag = true;
+
+                                            Map<Node, String> map = anchorNodeHash;
+                                            Iterator<Map.Entry<Node, String>> entries = map.entrySet().iterator();
+                                            while (entries.hasNext()) {
+                                                Map.Entry<Node, String> entry = entries.next();
+                                                entry.getKey();
+                                                hb.getChildren().remove(entry.getKey());
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+
+                        }
+
+
+                    }
+                    if (flag == false) {
+                        Map<Node, String> map = anchorNodeHash;
+                        Iterator<Map.Entry<Node, String>> entries = map.entrySet().iterator();
+                        while (entries.hasNext()) {
+                            Map.Entry<Node, String> entry = entries.next();
+                            entry.getKey();
+                            hb.getChildren().remove(entry.getKey());
+                            anchorFlag = false;
+                        }
+                    }
+                } catch (Exception e) {
+                }
+            }
+        });
+        con11.setOnMouseEntered(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent arg0) {
+                con11.setStroke(Color.GOLD);
+            }
+        });
+        con11.setOnMouseExited(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent arg0) {
+                con11.setStroke(Color.MIDNIGHTBLUE);
+            }
+        });
+        final DraggableNode contentLine = new DraggableNode();
+        con11.setOnMouseClicked(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent arg0) {
+                if (arg0.getClickCount() == 2) {
+                    topologyLink.start(new Stage());
+                    if (arrayOfLinkTopologyHash.isEmpty()) {
+                        for (HashMap<String, String> linkHash : arrayOfLinkTopologyHash) {
+                            Set linkSet = linkHash.entrySet();
+                            Iterator linkHashDetailIterator = linkSet.iterator();
+                            while (linkHashDetailIterator.hasNext()) {
+
+                                Map.Entry linkMap = (Map.Entry) linkHashDetailIterator.next();
+                                if (linkMap.getKey().toString().equals(con11.getId())) {
+                                    String[] linkValues = linkMap.getValue().toString().split("_");
+                                    topologyLink.nameText.setText(linkValues[0]);
+                                    topologyLink.typeText.setText(linkValues[1]);
+                                    topologyLink.devicesInTopoEditor.setEditable(true);
+                                    topologyLink.devicesInTopoEditor.getSelectionModel().select(linkValues[2]);
+                                    topologyLink.interfaceList2.setEditable(true);
+                                    topologyLink.interfaceList2.getSelectionModel().select(linkValues[3]);
+                                    topologyLink.destDevicesInTopoEditor.setEditable(true);
+                                    topologyLink.destDevicesInTopoEditor.getSelectionModel().select(linkValues[4]);
+                                    topologyLink.interfaceList4.setEditable(true);
+                                    topologyLink.interfaceList4.getSelectionModel().select(linkValues[5]);
+                                }
+                            }
+
+                        }
+                    }
+
+                    for (String string : draggedImagesName) {
+                        topologyLink.devicesInTopoEditor.getItems().add(string);
+                        topologyLink.destDevicesInTopoEditor.getItems().add(string);
+                    }
+                    topologyLink.devicesInTopoEditor.setOnAction(new EventHandler<ActionEvent>() {
+                        @Override
+                        public void handle(ActionEvent arg0) {
+                            topologyLink.interfaceList2.getItems().clear();
+                            try {
+                                for (HashMap<String, String> interFaceDetail : arrayOfInterFaceHash) {
+                                    Set set = interFaceDetail.entrySet();
+                                    Iterator interFaceHashDetailIterator = set.iterator();
+                                    while (interFaceHashDetailIterator.hasNext()) {
+                                        Map.Entry me = (Map.Entry) interFaceHashDetailIterator.next();
+                                        String[] deviceNameAndiniterFaceValue = me.getValue().toString().split("\\_");
+                                        if (deviceNameAndiniterFaceValue[1].equals(topologyLink.devicesInTopoEditor.getSelectionModel().getSelectedItem())) {
+                                            if (!me.getKey().toString().equals("")) {
+                                                topologyLink.interfaceList2.getItems().add(me.getKey().toString());
+                                            }
+                                        }
+                                    }
+                                }
+                            } catch (Exception e) {
+                            }
+                        }
+                    });
+
+                    topologyLink.destDevicesInTopoEditor.setOnAction(new EventHandler<ActionEvent>() {
+                        @Override
+                        public void handle(ActionEvent arg0) {
+
+                            topologyLink.interfaceList4.getItems().clear();
+                            try {
+                                for (HashMap<String, String> interFaceDetail : arrayOfInterFaceHash) {
+                                    Set set = interFaceDetail.entrySet();
+                                    Iterator interFaceHashDetailIterator = set.iterator();
+                                    while (interFaceHashDetailIterator.hasNext()) {
+                                        Map.Entry me = (Map.Entry) interFaceHashDetailIterator.next();
+                                        String[] deviceNameAndiniterFaceValue = me.getValue().toString().split("\\_");
+                                        if (deviceNameAndiniterFaceValue[1].equals(topologyLink.destDevicesInTopoEditor.getSelectionModel().getSelectedItem())) {
+                                            if (!me.getKey().toString().equals("")) {
+                                                topologyLink.interfaceList4.getItems().add(me.getKey().toString());
+                                            }
+                                        }
+                                    }
+                                }
+                            } catch (Exception e) {
+                            }
+                        }
+                    });
+                    topologyLink.finishSelectedLink.setOnAction(new EventHandler<ActionEvent>() {
+                        @Override
+                        public void handle(ActionEvent arg0) {
+                            con11.setId(topologyLink.nameText.getText() + "_" + con11.getStartX() + "_" + con11.getStartY() + "_" + con11.getEndX() + "_" + con11.getEndY());
+                            String detailedString = topologyLink.nameText.getText() + "_" + topologyLink.typeText.getText() + "_" + topologyLink.devicesInTopoEditor.getSelectionModel().getSelectedItem() + "_" + topologyLink.interfaceList2.getSelectionModel().getSelectedItem() + "_" + topologyLink.destDevicesInTopoEditor.getSelectionModel().getSelectedItem() + "_" + topologyLink.interfaceList4.getSelectionModel().getSelectedItem() + "_";
+                            linkTopologyHash.put(con11.getId(), detailedString);
+                            arrayOfLinkTopologyHash = new ArrayList<HashMap<String, String>>();
+                            arrayOfLinkTopologyHash.add(linkTopologyHash);
+                            topologyLink.copyStage.close();
+                        }
+                    });
+                } else if (arg0.getButton() == MouseButton.SECONDARY) {
+                }
+            }
+        });
+    }
+
+    public void closeNodeOnCanvas(final Button closeButton, final VBox hbox, final Pane hb, final DraggableNode content) {
+        final ArrayList<Node> removeNodes = new ArrayList<Node>();
+
+        closeButton.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent arg0) {
+                Node parent = hbox.getParent();
+                ObservableList<Node> allCurrentNode = hb.getChildren();
+                for (Node node : allCurrentNode) {
+                    if (node.toString().contains("Line")) {
+                        if (!node.toString().matches("Line[id=Line[id=null,null]]")) {
+                            if (node.getId() != null) {
+                                String[] startLineNode = node.getId().split(",");
+                                Integer nodeHash = content.hashCode();
+                                if (nodeHash.toString().equals(startLineNode[0])) {
+                                    removeNodes.add(node);
+                                }
+                                if (startLineNode.length == 2) {
+                                    if (nodeHash.toString().equals(startLineNode[1])) {
+                                        removeNodes.add(node);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+
+                for (Node removenode : removeNodes) {
+                    hb.getChildren().remove(removenode);
+                }
+
+                hb.getChildren().remove(content);
+            }
+        });
+    }
+
+    private void enableDrag(final Circle circle) {
+        final OFAAnchorInsideImageNode.Delta dragDelta = new OFAAnchorInsideImageNode.Delta();
+
+        circle.setOnMousePressed(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent mouseEvent) {
+                dragDelta.x = circle.getCenterX() - mouseEvent.getX();
+                dragDelta.y = circle.getCenterY() - mouseEvent.getY();
+                circle.getScene().setCursor(Cursor.MOVE);
+            }
+        });
+
+        circle.setOnMouseReleased(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent mouseEvent) {
+            }
+        });
+
+        circle.setOnMouseDragged(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent mouseEvent) {
+                circle.setCenterX(mouseEvent.getX() + dragDelta.x);
+                circle.setCenterY(mouseEvent.getY() + dragDelta.y);
+            }
+        });
+
+        circle.setOnMouseEntered(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent mouseEvent) {
+                if (!mouseEvent.isPrimaryButtonDown()) {
+                    circle.getScene().setCursor(Cursor.HAND);
+                }
+            }
+        });
+
+        circle.setOnMouseExited(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent mouseEvent) {
+                if (!mouseEvent.isPrimaryButtonDown()) {
+                }
+            }
+        });
+    }
+
+    class Anchor extends Circle {
+
+        Anchor(String id, DoubleProperty x, DoubleProperty y) {
+            super(x.get(), y.get(), 7);
+            setId(id);
+            setFill(Color.ANTIQUEWHITE.deriveColor(1, 1, 1, 0.75));
+            setStroke(Color.GREY);
+            x.bind(centerXProperty());
+            y.bind(centerYProperty());
+        }
+    }
+
+    class Delta {
+
+        double x, y;
+    }
+}
diff --git a/TestON/TAI/src/tai_ofa/OFAContentHelp.java b/TestON/TAI/src/tai_ofa/OFAContentHelp.java
new file mode 100644
index 0000000..083daf5
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/OFAContentHelp.java
@@ -0,0 +1,705 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package tai_ofa;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.geometry.Side;
+import javafx.scene.Group;
+import javafx.scene.control.ContextMenu;
+import javafx.scene.control.Label;
+import javafx.scene.control.ListView;
+import javafx.scene.control.MenuItem;
+import javafx.scene.control.TextField;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.StackPane;
+
+/**
+ *
+ * @author Raghav kashyap (raghavkashyap@paxterrasolutions.com)
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+ */
+public class OFAContentHelp {
+
+    ContextMenu assertContext;
+    ArrayList<MenuItem> assertNameList;
+    CodeEditor Content;
+    TAI_OFA OFAReference;
+    String ospkCommand;
+    boolean keyPressed = false;
+    ArrayList<String> checkBuffer;
+    ContextMenu contextMenu, driverFunctionContextMenu;
+    ArrayList<String> myDevices;
+    ArrayList<MenuItem> myMenuItems;
+    ArrayList<String> driverFunctionName;
+    ArrayList<MenuItem> functionMenuItem;
+    OFAParamDeviceName paramFile;
+    String deviceTypePath;
+    ContextMenu commandNameContextMenu, withContextMenu, runDriverContextMenu;
+    ArrayList<MenuItem> bdtFunction;
+    String selectedDeviceName;
+    String selectedFunctionName;
+    TextField paraMeterListText;
+    ArrayList<String> parameterArrayList = new ArrayList<String>();
+    ArrayList<TextField> parameterTextFieldList = new ArrayList<TextField>();
+    String matchedCase;
+    ArrayList<Label> parameterLabel = new ArrayList<Label>();
+    OFAFileOperations fileOperation = new OFAFileOperations();
+    ObservableList<String> data;
+    Group popupRoot;
+    ListView<String> seleniumFunctionListView, cliFunctionListView;
+    String baseDeviceDriver, cliFunctionStr;
+    ArrayList<String> cliFunctionList = new ArrayList<String>();
+    HashMap<String, String> cliFunctionWithArgumentMap = new HashMap<String, String>();
+    String selectedCLiFunction;
+    String selectedSeleniumFunction;
+    TAILocale label = new TAILocale(new Locale("en", "EN"));
+    String OFAHarnessPath = label.hierarchyTestON;
+    String bdrPath;
+    String selectedDeviceType;
+
+    public OFAContentHelp() {
+    }
+
+    public OFAContentHelp(CodeEditor editor, TAI_OFA reference) {
+        this.Content = editor;
+        OFAReference = reference;
+    }
+
+    public void assertContextMenu() {
+        assertContext = new ContextMenu();
+        MenuItem equal = new MenuItem("EQUALS");
+        MenuItem match = new MenuItem("MATCHES");
+        MenuItem greater = new MenuItem("GREATER");
+        MenuItem lesser = new MenuItem("LESSER");
+        assertNameList = new ArrayList<MenuItem>();
+        assertNameList.add(equal);
+        assertNameList.add(match);
+        assertNameList.add(greater);
+        assertNameList.add(lesser);
+        assertContext.getItems().addAll(equal, match, greater, lesser);
+    }
+
+    public void ospkHelp() {
+
+        Content.addEventHandler(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
+            @Override
+            public void handle(KeyEvent keyEvent) {
+                if (keyEvent.getCode() == KeyCode.SPACE) {
+                    ArrayList<Integer> existingCaseNumber = new ArrayList<Integer>();
+                    existingCaseNumber.add(0);
+                    String[] content = Content.getCodeAndSnapshot().split("\n");
+                    for (int i = 0; i < content.length; i++) {
+                        Pattern pattern = Pattern.compile("CASE\\s+(\\d+)\\s*");
+                        Matcher matchCase = pattern.matcher(content[i]);
+
+                        while (matchCase.find()) {
+                            try {
+                                int number = Integer.parseInt(matchCase.group(1));
+                                existingCaseNumber.add(number);
+                            } catch (Exception e) {
+                            }
+                        }
+                    }
+
+                    int max = Collections.max(existingCaseNumber);
+                    max = max + 1;
+                    String caseNumbers = String.valueOf(max);
+                    Content.setLine(Integer.parseInt(Content.getCurrentLineNumber()), Content.getCurrentLine().replace("CASE", "CASE" + " " + caseNumbers));
+                }
+
+                Pattern namePattern = Pattern.compile("\\s*NAME\\s+(.*)");
+                Pattern descPattern = Pattern.compile("DESC\\s+(.*)");
+                Pattern stepPattern = Pattern.compile("STEP\\s+(.*)");
+                Pattern onPattern = Pattern.compile("ON\\s+(.*)");
+                Pattern cmdPattern = Pattern.compile("ON\\s+(\\w+\\s+(.*))");
+                Pattern runPattern = Pattern.compile("" + ospkCommand + "\\s+(.*)");
+                Pattern assertPattern = Pattern.compile("ASSERT\\s+(.*)");
+                Pattern usingPattern = Pattern.compile("(.*)\\s+USING\\s+");
+                String[] OFAEditorLine = Content.getCodeAndSnapshot().split("\n");
+
+                final Matcher onMatch = onPattern.matcher(Content.getCurrentLine());
+                final Matcher cmdMatch = cmdPattern.matcher(Content.getCurrentLine());
+                final Matcher runMatch = runPattern.matcher(Content.getCurrentLine());
+                final Matcher asertMatch = assertPattern.matcher(Content.getCurrentLine());
+                final Matcher usingMatch = usingPattern.matcher(Content.getCurrentLine());
+                Matcher nameMatch = namePattern.matcher(Content.getCurrentLine());
+                Matcher descMatch = descPattern.matcher(Content.getCurrentLine());
+                Matcher stepMatch = stepPattern.matcher(Content.getCurrentLine());
+                while (nameMatch.find()) {
+                    if (nameMatch.group(1).isEmpty()) {
+                        if (keyEvent.getCode() == KeyCode.SPACE) {
+                            Content.setLine(Integer.parseInt(Content.getCurrentLineNumber()), Content.getCurrentLine().replace("NAME", "NAME" + " " + "\"\""));
+                        }
+
+                    }
+                }
+
+                while (descMatch.find()) {
+                    if (descMatch.group(1).isEmpty()) {
+                        if (keyEvent.getCode() == KeyCode.SPACE) {
+                            Content.setLine(Integer.parseInt(Content.getCurrentLineNumber()), Content.getCurrentLine().replace("DESC", "DESC" + " " + "\"\""));
+                        }
+
+                    }
+                }
+
+                while (stepMatch.find()) {
+                    if (stepMatch.group(1).isEmpty()) {
+                        if (keyEvent.getCode() == KeyCode.SPACE) {
+                            Content.setLine(Integer.parseInt(Content.getCurrentLineNumber()), Content.getCurrentLine().replace("STEP", "STEP" + " " + "\"\""));
+                        }
+
+                    }
+                }
+
+
+                while (onMatch.find()) {
+                    if (onMatch.group(1).isEmpty()) {
+                        if (keyEvent.getCode() == KeyCode.getKeyCode("Ctrl")) {
+                            keyPressed = true;
+                        }
+
+                        if (keyPressed == true) {
+                            if (keyEvent.getCode() == KeyCode.SPACE) {
+                                keyPressed = false;
+                                onMatch.group();
+                                onDeviceContextMenu();
+                                contextMenu.show(OFAReference.editorTabPane, Side.TOP, Content.cursorPosfromLeft(), Content.cursorPosfromTop() + 65);
+                                for (final MenuItem myMenuItem : myMenuItems) {
+                                    myMenuItem.setOnAction(new EventHandler<ActionEvent>() {
+                                        @Override
+                                        public void handle(ActionEvent arg0) {
+                                            HashMap<String, String> deviceNameAndType = paramFile.getdeviceNameAndType();
+                                            Iterator paramIterator = deviceNameAndType.entrySet().iterator();
+                                            while (paramIterator.hasNext()) {
+                                                Map.Entry mEntry = (Map.Entry) paramIterator.next();
+                                                if (myMenuItem.getText().equals(mEntry.getKey())) {
+                                                    selectedDeviceType = mEntry.getValue().toString();
+                                                    selectedDeviceType = selectedDeviceType.replaceAll("\\s+", "");
+                                                    String driverTypePath = OFAHarnessPath + "/drivers/common/";
+                                                    File aFile = new File(driverTypePath);
+                                                    fileOperation.Process(aFile);
+                                                    for (String path : fileOperation.filePath) {
+                                                        String[] splitPath = path.split("\\/");
+                                                        String[] fileName = splitPath[splitPath.length - 1].split("\\.");
+                                                        for (int p = 0; p < fileName.length; p++) {
+                                                            if ((selectedDeviceType).equals(fileName[p])) {
+                                                                deviceTypePath = path;
+                                                                bdrPath = deviceTypePath.replaceAll("py", "ospk");
+                                                            }
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                            selectedDeviceName = myMenuItem.getText();
+                                            Content.setLine(Integer.parseInt(Content.getCurrentLineNumber()), Content.getCurrentLine().replace("ON", "ON" + " " + myMenuItem.getText()));
+                                        }
+                                    });
+                                }
+                            }
+                        }
+
+                    }
+                }
+                while (cmdMatch.find()) {
+                    if (cmdMatch.group(2).isEmpty()) {
+                        if (keyEvent.getCode() == KeyCode.getKeyCode("Ctrl")) {
+                            keyPressed = true;
+                        }
+
+                        if (keyPressed == true) {
+                            if (keyEvent.getCode() == KeyCode.SPACE) {
+                                runContextMenu();
+                                commandNameContextMenu.show(OFAReference.editorTabPane, Side.TOP, Content.cursorPosfromLeft(), Content.cursorPosfromTop() + 115);
+                                for (final MenuItem bdtCmd : bdtFunction) {
+                                    bdtCmd.setOnAction(new EventHandler<ActionEvent>() {
+                                        @Override
+                                        public void handle(ActionEvent t) {
+                                            ospkCommand = bdtCmd.getText();
+                                            Content.setLine(Integer.parseInt(Content.getCurrentLineNumber()), Content.getCurrentLine().replace(selectedDeviceName, selectedDeviceName + " " + bdtCmd.getText()));
+                                        }
+                                    });
+                                }
+                            }
+                        }
+                    }
+                }
+
+                while (runMatch.find()) {
+
+                    if (runMatch.group(1).isEmpty()) {
+                        if (keyEvent.getCode() == KeyCode.getKeyCode("Ctrl")) {
+                            keyPressed = true;
+                        }
+                        if (keyPressed == true) {
+                            if (keyEvent.getCode() == KeyCode.SPACE) {
+                                keyPressed = false;
+
+                                onDriverContextMenu();
+                                driverFunctionContextMenu.show(OFAReference.editorTabPane, Side.TOP, Content.cursorPosfromLeft(), Content.cursorPosfromTop() + 65);
+
+                                Group popupRoot = (Group) driverFunctionContextMenu.getScene().getRoot();
+                                final ListView<String> driverFunctionListView = new ListView<String>();
+                                data = FXCollections.observableArrayList();
+                                for (String function : driverFunctionName) {
+                                    data.add(function);
+                                }
+                                driverFunctionListView.setItems(data);
+                                driverFunctionListView.setMaxHeight(100);
+                                driverFunctionListView.setMaxWidth(150);
+                                driverFunctionListView.getSelectionModel().selectFirst();
+
+                                driverFunctionListView.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
+                                    @Override
+                                    public void handle(KeyEvent arg0) {
+                                        if (arg0.getCode() == KeyCode.ENTER || arg0.getCode() == KeyCode.SPACE) {
+                                            selectedFunctionName = driverFunctionListView.getSelectionModel().getSelectedItem().toString();
+                                            Content.setLine(Integer.parseInt(Content.getCurrentLineNumber()), Content.getCurrentLine().replace("RUN", "RUN" + " " + selectedFunctionName));
+                                            driverFunctionContextMenu.hide();
+                                        }
+                                    }
+                                });
+                                popupRoot.getChildren().add(driverFunctionListView);
+                                driverFunctionListView.requestFocus();
+                            }
+                        }
+                    }
+                }
+
+                while (asertMatch.find()) {
+                    if (asertMatch.group(1).isEmpty()) {
+                        if (keyEvent.getCode() == KeyCode.getKeyCode("Ctrl")) {
+                            keyPressed = true;
+                        }
+
+                        if (keyPressed == true) {
+                            if (keyEvent.getCode() == KeyCode.SPACE) {
+                                OFAContentHelp contentHelp = new OFAContentHelp();
+                                contentHelp.assertContextMenu();
+                                contentHelp.assertContext.show(OFAReference.editorTabPane, Side.TOP, Content.cursorPosfromLeft(), Content.cursorPosfromTop() + 65);
+                                for (final MenuItem assertCommand : contentHelp.assertNameList) {
+                                    assertCommand.setOnAction(new EventHandler<ActionEvent>() {
+                                        @Override
+                                        public void handle(ActionEvent t) {
+                                            Content.setLine(Integer.parseInt(Content.getCurrentLineNumber()), Content.getCurrentLine().replace("ASSERT", "ASSERT " + assertCommand.getText()));
+                                        }
+                                    });
+                                }
+                            }
+                        }
+                    }
+
+                }
+
+                while (usingMatch.find()) {
+                    if (!usingMatch.group(1).isEmpty()) {
+                        if (keyEvent.getCode() == KeyCode.CONTROL) {
+                            keyPressed = true;
+                        }
+
+                        if (keyPressed == true) {
+                            if (keyEvent.getCode() == KeyCode.SPACE) {
+                                OFAParamDeviceName paramDeice = new OFAParamDeviceName();
+                                if (selectedDeviceType.equals("poxclidriver")) {
+                                    String baseCliDevice = bdrPath.replace(bdrPath, label.hierarchyTestON + "/drivers/common/cli/emulator/poxclidriver.py");
+                                    paramDeice.driverFunctionName(baseCliDevice);
+                                    for (String functionName : paramDeice.driverFunctionName) {
+                                        driverFunctionName.add(functionName);
+                                    }
+                                } else if (selectedDeviceType.equals("mininetclidriver")) {
+                                    String baseCliDevice = bdrPath.replace(bdrPath, label.hierarchyTestON + "/drivers/common/cli/emulator/mininetclidriver.py");
+                                    paramDeice.driverFunctionName(baseCliDevice);
+                                    for (String functionName : paramDeice.driverFunctionName) {
+                                        driverFunctionName.add(functionName);
+                                    }
+                                } else if (selectedDeviceType.equals("hpswitchclidriver")) {
+                                    String baseCliDevice = bdrPath.replace(bdrPath, label.hierarchyTestON + "/drivers/common/cli/remotetestbed/hpswitchclidriver.py");
+                                    paramDeice.driverFunctionName(baseCliDevice);
+                                    for (String functionName : paramDeice.driverFunctionName) {
+                                        driverFunctionName.add(functionName);
+                                    }
+                                }
+                                if (selectedDeviceType.equals("flowvisorclidriver")) {
+                                    String baseCliDevice = bdrPath.replace(bdrPath, label.hierarchyTestON + "/drivers/common/cli/remotesys/flowvisorclidriver.py");
+                                    paramDeice.driverFunctionName(baseCliDevice);
+                                    for (String functionName : paramDeice.driverFunctionName) {
+                                        driverFunctionName.add(functionName);
+                                    }
+                                }
+                                if (selectedDeviceType.equals("floodlightclidriver")) {
+                                    String baseCliDevice = bdrPath.replace(bdrPath, label.hierarchyTestON + "/drivers/common/cli/remotesys/floodlightclidriver.py");
+                                    paramDeice.driverFunctionName(baseCliDevice);
+                                    for (String functionName : paramDeice.driverFunctionName) {
+                                        driverFunctionName.add(functionName);
+                                    }
+                                }
+                                if (selectedDeviceType.equals("remotepoxdriver")) {
+                                    String baseCliDevice = bdrPath.replace(bdrPath, label.hierarchyTestON + "/drivers/common/cli/remotesys/remotepoxdriver.py");
+                                    paramDeice.driverFunctionName(baseCliDevice);
+                                    for (String functionName : paramDeice.driverFunctionName) {
+                                        driverFunctionName.add(functionName);
+                                    }
+                                }
+                                if (selectedDeviceType.equals("remotevmdriver")) {
+                                    String baseCliDevice = bdrPath.replace(bdrPath, label.hierarchyTestON + "/drivers/common/cli/remotesys/remotevmdriver.py");
+                                    paramDeice.driverFunctionName(baseCliDevice);
+                                    for (String functionName : paramDeice.driverFunctionName) {
+                                        driverFunctionName.add(functionName);
+                                    }
+                                }
+                                if (selectedDeviceType.equals("dpctlclidriver")) {
+                                    String baseCliDevice = bdrPath.replace(bdrPath, label.hierarchyTestON + "/drivers/common/cli/tool/dpctlclidriver.py");
+                                    paramDeice.driverFunctionName(baseCliDevice);
+                                    for (String functionName : paramDeice.driverFunctionName) {
+                                        driverFunctionName.add(functionName);
+                                    }
+                                }
+                                if (selectedDeviceType.equals("fvtapidriver")) {
+                                    String baseCliDevice = bdrPath.replace(bdrPath, label.hierarchyTestON + "/drivers/common/api/fvtapidriver.py");
+                                    paramDeice.driverFunctionName(baseCliDevice);
+                                    for (String functionName : paramDeice.driverFunctionName) {
+                                        driverFunctionName.add(functionName);
+                                    }
+                                }
+                                HashMap<String, String> functionAndParameter = paramDeice.functionWithParameter;
+                                Set set = functionAndParameter.entrySet();
+                                // Get an iterator
+                                Iterator functionAndParameterIterator = set.iterator();
+                                // Display elements
+                                final GridPane paramPanel = new GridPane();
+                                paramPanel.setStyle("-fx-background-color: DAE6F3;");
+                                String caseParameter = "";
+                                parameterLabel.clear();
+                                parameterTextFieldList.clear();
+                                while (functionAndParameterIterator.hasNext()) {
+                                    Map.Entry functionInfo = (Map.Entry) functionAndParameterIterator.next();
+                                    if (selectedFunctionName.equals(functionInfo.getKey().toString())) {
+                                        String[] splitParameter = functionInfo.getValue().toString().split("\\,");
+                                        if (splitParameter.length > 0) {
+                                            for (int j = 0; j < splitParameter.length; j++) {
+                                                Label parameterList = new Label();
+                                                parameterLabel.add(parameterList);
+                                                paraMeterListText = new TextField();
+                                                parameterList.setText(splitParameter[j]);
+                                                paramPanel.add(parameterList, 0, j);
+                                                paramPanel.add(paraMeterListText, 1, j);
+                                                parameterTextFieldList.add(paraMeterListText);
+                                                caseParameter += splitParameter[j].toLowerCase() + "AS " + "CASE" + "[" + splitParameter[j].toLowerCase() + "]" + ",";
+                                            }
+                                        }
+                                    }
+                                }
+                                withContextMenu();
+                                withContextMenu.show(OFAReference.editorTabPane, Side.TOP, Content.cursorPosfromLeft(), Content.cursorPosfromTop() + 65);
+                                Group popupRoot = (Group) withContextMenu.getScene().getRoot();
+                                Group popupCSSBridge = (Group) popupRoot.getChildren().get(0);
+                                StackPane popupContent = (StackPane) popupCSSBridge.getChildren().get(0);
+                                popupRoot.getChildren().add(paramPanel);
+                                if (!caseParameter.equals("")) {
+                                    try {
+                                        caseParameter = caseParameter.substring(0, caseParameter.length() - 1);
+                                    } catch (ArrayIndexOutOfBoundsException e) {
+                                    }
+                                }
+                                popupContent.setMaxHeight(OFAReference.editorTabPane.getHeight() - 400);
+                                Content.setLine(Integer.parseInt(Content.getCurrentLineNumber()), Content.getCurrentLine().replace("USING", "USING" + " " + caseParameter));
+                                for (int k = Integer.parseInt(Content.getCurrentLineNumber()); k > 0; k--) {
+                                    Pattern firstUpperCasePattern = Pattern.compile("CASE\\s+(\\d)");
+                                    Matcher firstUpperCaseMatch = firstUpperCasePattern.matcher(Content.getCurrentLine(k));
+                                    if (firstUpperCaseMatch.find()) {
+                                        matchedCase = firstUpperCaseMatch.group();
+                                        break;
+                                    }
+                                }
+                                try {
+                                    paraMeterListText.setOnKeyPressed(new EventHandler<KeyEvent>() {
+                                        @Override
+                                        public void handle(KeyEvent keyEvent) {
+                                            if (keyEvent.getCode() == KeyCode.ENTER) {
+                                                String paramCaseContent = "";
+                                                String matchCaseWithoutSpace = matchedCase.replaceAll("\\s+", "");
+                                                String currentTabPath = OFAReference.editorTabPane.getSelectionModel().getSelectedItem().getId();
+                                                String paramFile = currentTabPath.replace(fileOperation.getExtension(currentTabPath), ".params");
+                                                Pattern matchCasePattern = Pattern.compile("^\\s*\\<" + matchCaseWithoutSpace + "\\>");
+                                                String fileContent[] = fileOperation.getContents(new File(paramFile)).split("\n");
+                                                String myCase = "";
+                                                Boolean caseFlag = false;
+                                                int k;
+                                                for (k = 0; k < fileContent.length; k++) {
+                                                    Matcher caseMatch = matchCasePattern.matcher(fileContent[k]);
+                                                    if (caseMatch.find()) {
+                                                        myCase = caseMatch.group();
+                                                        caseFlag = true;
+                                                        break;
+                                                    }
+                                                }
+                                                if (caseFlag == true) {
+                                                    String remainingConetent = "";
+                                                    int caseVarible = k;
+                                                    k++;
+                                                    for (; k < fileContent.length; k++) {
+                                                        remainingConetent += "\n" + fileContent[k];
+                                                    }
+                                                    String allContent = "";
+                                                    allContent += fileContent[0];
+                                                    for (int p = 1; p < caseVarible; p++) {
+                                                        allContent += "\n" + fileContent[p];
+                                                    }
+                                                    allContent += "\n\t<" + matchCaseWithoutSpace + ">";
+
+                                                    for (int i = 0; i < parameterTextFieldList.size(); i++) {
+                                                        String parameterLabels = parameterLabel.get(i).getText().replaceAll("\"", "");
+                                                        paramCaseContent += "\n\t\t<" + parameterLabels.toLowerCase() + ">" + parameterTextFieldList.get(i).getText() + "</" + parameterLabels.toLowerCase() + ">";
+                                                    }
+
+                                                    allContent += paramCaseContent;
+                                                    allContent += remainingConetent;
+                                                    String paramFilePath = OFAReference.editorTabPane.getSelectionModel().getSelectedItem().getId().replace(fileOperation.getExtension(OFAReference.editorTabPane.getSelectionModel().getSelectedItem().getId()), ".params");
+                                                    String paramFileContent = fileOperation.getContents(new File(paramFilePath));
+                                                    try {
+                                                        fileOperation.setContents(new File(paramFilePath), allContent);
+                                                    } catch (FileNotFoundException ex) {
+                                                        Logger.getLogger(OFAContentHelp.class.getName()).log(Level.SEVERE, null, ex);
+                                                    } catch (IOException ex) {
+                                                        Logger.getLogger(OFAContentHelp.class.getName()).log(Level.SEVERE, null, ex);
+                                                    }
+                                                    withContextMenu.hide();
+                                                    paramPanel.setVisible(false);
+                                                } else {
+                                                    paramCaseContent += "<" + matchCaseWithoutSpace + ">";
+                                                    for (int i = 0; i < parameterTextFieldList.size(); i++) {
+                                                        paramCaseContent += "\n\t\t<" + parameterLabel.get(i).getText().toLowerCase() + ">" + parameterTextFieldList.get(i).getText() + "</" + parameterLabel.get(i).getText().toLowerCase() + ">";
+                                                    }
+
+                                                    paramCaseContent += "\n\t" + "</" + matchCaseWithoutSpace + ">";
+                                                    String paramFilePath = OFAReference.editorTabPane.getSelectionModel().getSelectedItem().getId().replace(fileOperation.getExtension(OFAReference.editorTabPane.getSelectionModel().getSelectedItem().getId()), ".params");
+                                                    String paramFileContent = fileOperation.getContents(new File(paramFilePath));
+                                                    String removeTestParam = paramFileContent.replace("</TEST_PARAMS>", " ");
+                                                    removeTestParam += "\t" + paramCaseContent + "\n\n" + "</TEST_PARAMS>";
+                                                    try {
+                                                        fileOperation.setContents(new File(paramFilePath), removeTestParam);
+                                                    } catch (FileNotFoundException ex) {
+                                                        Logger.getLogger(OFAContentHelp.class.getName()).log(Level.SEVERE, null, ex);
+                                                    } catch (IOException ex) {
+                                                        Logger.getLogger(OFAContentHelp.class.getName()).log(Level.SEVERE, null, ex);
+                                                    }
+                                                    withContextMenu.hide();
+                                                    paramPanel.setVisible(false);
+                                                }
+                                            }
+                                        }
+                                    });
+                                } catch (Exception e) {
+                                }
+
+                            }
+                        }
+                    }
+
+                }
+
+                checkBuffer = new ArrayList<String>();
+
+                if (keyEvent.getCode() == KeyCode.ENTER) {
+                    String bufferedString = "";
+                    for (String s : checkBuffer) {
+                        bufferedString += s;
+                    }
+                    Pattern pattern = Pattern.compile("CASE\\s+(\\d+)");
+                    Matcher match = pattern.matcher(bufferedString);
+                    while (match.find()) {
+                        Content.setCode(Content.getCodeAndSnapshot().replaceAll(bufferedString, bufferedString + "\n\n" + "END CASE"));
+                    }
+                    checkBuffer.clear();
+                }
+
+            }
+        });
+
+        Content.setOnKeyPressed(new EventHandler<KeyEvent>() {
+            @Override
+            public void handle(KeyEvent arg0) {
+                String text = arg0.getText();
+                if (arg0.getCode() == KeyCode.ENTER) {
+                } else if (arg0.getCode() == KeyCode.BACK_SPACE) {
+                } else {
+                    checkBuffer.add(text);
+                }
+            }
+        });
+    }
+
+    public void onDeviceContextMenu() {
+        contextMenu = new ContextMenu();
+        myDevices = new ArrayList<String>();
+        ArrayList<String> paramDeviceType = new ArrayList<String>();
+        myMenuItems = new ArrayList<MenuItem>();
+
+        String selectedTabPath = OFAReference.editorTabPane.getSelectionModel().getSelectedItem().getId();
+        String[] splitSelectedPath = selectedTabPath.split("\\/");
+        String[] ospkFileName = splitSelectedPath[splitSelectedPath.length - 1].toString().split("\\.");
+        String paramFileName = ospkFileName[0] + ".topo";
+        String paramFilePath = selectedTabPath.replace(splitSelectedPath[splitSelectedPath.length - 1].toString(), paramFileName);
+        paramFile = new OFAParamDeviceName(paramFilePath, "");
+        paramFile.parseParamFile();
+
+        for (String deviceName : paramFile.getParamDeviceName()) {
+            myDevices.add(deviceName);
+        }
+
+        for (String myDevice : myDevices) {
+            final MenuItem myMenuItem = new MenuItem(myDevice);
+            myMenuItem.setOnAction(new EventHandler<ActionEvent>() {
+                @Override
+                public void handle(ActionEvent arg0) {
+                }
+            });
+            myMenuItems.add(myMenuItem);
+        }
+
+        for (MenuItem myMenuItem : myMenuItems) {
+            contextMenu.getItems().addAll(myMenuItem);
+
+        }
+
+        OFAReference.editorTabPane.setContextMenu(contextMenu);
+    }
+
+    public void onDriverContextMenu() {
+        driverFunctionContextMenu = new ContextMenu();
+        driverFunctionName = new ArrayList<String>();
+        driverFunctionName.clear();
+        OFAParamDeviceName driverFile = new OFAParamDeviceName();
+
+        if (selectedDeviceType.equals("poxclidriver")) {
+            String baseCliDevice = bdrPath.replace(bdrPath, label.hierarchyTestON + "/drivers/common/cli/emulator/poxclidriver.py");
+            driverFile.driverFunctionName(baseCliDevice);
+            for (String functionName : driverFile.driverFunctionName) {
+                driverFunctionName.add(functionName);
+            }
+        } else if (selectedDeviceType.equals("mininetclidriver")) {
+            String baseCliDevice = bdrPath.replace(bdrPath, label.hierarchyTestON + "/drivers/common/cli/emulator/mininetclidriver.py");
+            driverFile.driverFunctionName(baseCliDevice);
+            for (String functionName : driverFile.driverFunctionName) {
+                driverFunctionName.add(functionName);
+            }
+        }
+        if (selectedDeviceType.equals("hpswitchdriver")) {
+            String baseCliDevice = bdrPath.replace(bdrPath, label.hierarchyTestON + "/drivers/common/cli/remotesys/hpswitchdriver.py");
+            driverFile.driverFunctionName(baseCliDevice);
+            for (String functionName : driverFile.driverFunctionName) {
+                driverFunctionName.add(functionName);
+            }
+        }
+        if (selectedDeviceType.equals("dpctlclidriver")) {
+            String baseCliDevice = bdrPath.replace(bdrPath, label.hierarchyTestON + "/drivers/common/cli/tool/dpctlclidriver.py");
+            driverFile.driverFunctionName(baseCliDevice);
+            for (String functionName : driverFile.driverFunctionName) {
+                driverFunctionName.add(functionName);
+            }
+        }
+        if (selectedDeviceType.equals("fvtapidriver")) {
+            String baseCliDevice = bdrPath.replace(bdrPath, label.hierarchyTestON + "/drivers/common/api/fvtapidriver.py");
+            driverFile.driverFunctionName(baseCliDevice);
+            for (String functionName : driverFile.driverFunctionName) {
+                driverFunctionName.add(functionName);
+            }
+        } else if (selectedDeviceType.equals("hpswitchclidriver")) {
+            String baseCliDevice = bdrPath.replace(bdrPath, label.hierarchyTestON + "/drivers/common/cli/remotetestbed/hpswitchclidriver.py");
+            driverFile.driverFunctionName(baseCliDevice);
+            for (String functionName : driverFile.driverFunctionName) {
+                driverFunctionName.add(functionName);
+            }
+        }
+        if (selectedDeviceType.equals("flowvisorclidriver")) {
+            String baseCliDevice = bdrPath.replace(bdrPath, label.hierarchyTestON + "/drivers/common/cli/remotetestbed/flowvisorclidriver.py");
+            driverFile.driverFunctionName(baseCliDevice);
+            for (String functionName : driverFile.driverFunctionName) {
+                driverFunctionName.add(functionName);
+            }
+        }
+        if (selectedDeviceType.equals("floodlightclidriver")) {
+            String baseCliDevice = bdrPath.replace(bdrPath, label.hierarchyTestON + "/drivers/common/cli/remotetestbed/floodlightclidriver.py");
+            driverFile.driverFunctionName(baseCliDevice);
+            for (String functionName : driverFile.driverFunctionName) {
+                driverFunctionName.add(functionName);
+            }
+        }
+        if (selectedDeviceType.equals("remotepoxdriver")) {
+            String baseCliDevice = bdrPath.replace(bdrPath, label.hierarchyTestON + "/drivers/common/cli/remotetestbed/remotepoxdriver.py");
+            driverFile.driverFunctionName(baseCliDevice);
+            for (String functionName : driverFile.driverFunctionName) {
+                driverFunctionName.add(functionName);
+            }
+        }
+        if (selectedDeviceType.equals("remotevmdriver")) {
+            String baseCliDevice = bdrPath.replace(bdrPath, label.hierarchyTestON + "/drivers/common/cli/remotetestbed/remotevmdriver.py");
+            driverFile.driverFunctionName(baseCliDevice);
+            for (String functionName : driverFile.driverFunctionName) {
+                driverFunctionName.add(functionName);
+            }
+        }
+        driverFunctionContextMenu.getItems().add(new MenuItem());
+    }
+
+    public void runContextMenu() {
+        commandNameContextMenu = new ContextMenu();
+        MenuItem run = new MenuItem("RUN");
+        MenuItem exec = new MenuItem("EXEC");
+        MenuItem config = new MenuItem("CONFIG");
+        bdtFunction = new ArrayList<MenuItem>();
+        bdtFunction.add(run);
+        bdtFunction.add(exec);
+        bdtFunction.add(config);
+        commandNameContextMenu.getItems().addAll(run, exec, config);
+    }
+
+    public void withContextMenu() {
+        withContextMenu = new ContextMenu();
+        MenuItem item = new MenuItem();
+        withContextMenu.getItems().add(item);
+        item.setDisable(true);
+    }
+
+    // drivers context menu
+    public void runDriverContextMenu() {
+        runDriverContextMenu = new ContextMenu();
+        MenuItem runDriverMenuItem = new MenuItem("");
+        runDriverContextMenu.getItems().add(runDriverMenuItem);
+    }
+}
diff --git a/TestON/TAI/src/tai_ofa/OFAFileOperations.java b/TestON/TAI/src/tai_ofa/OFAFileOperations.java
new file mode 100644
index 0000000..9296502
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/OFAFileOperations.java
@@ -0,0 +1,168 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package tai_ofa;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.ArrayList;
+
+/**
+ *
+ * @author Raghav Kashyap (raghavkashyap@paxterrasolutions.com)
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+ */
+public class OFAFileOperations {
+
+    BufferedReader input;
+    ArrayList list = new ArrayList();
+    ArrayList<String> filePath = new ArrayList<String>();
+
+    public OFAFileOperations() {
+    }
+
+    public void writeInFile(String path, String demoFile) {
+        try {
+            FileWriter fstream = new FileWriter(path);
+            BufferedWriter out = new BufferedWriter(fstream);
+            out.write(demoFile);
+            out.close();
+        } catch (Exception e) {
+        }
+    }
+
+    public String getContents(File aFile) {
+        StringBuilder contents = new StringBuilder();
+
+        try {
+            //use buffering, reading one line at a time
+            //FileReader always assumes default encoding is OK!
+            try {
+                input = new BufferedReader(new FileReader(aFile));
+            } catch (Exception e) {
+            }
+
+            try {
+                String line = null; //not declared within while loop
+
+                while ((line = input.readLine()) != null) {
+                    contents.append(line);
+                    contents.append(System.getProperty("line.separator"));
+                }
+            } finally {
+                try {
+                    input.close();
+                } catch (Exception e) {
+                }
+
+            }
+        } catch (IOException ex) {
+            ex.printStackTrace();
+        }
+
+        return contents.toString();
+    }
+
+    public String getExtension(String name) {
+        String extension = null;
+        try {
+
+            if (name.contains(".")) {
+                int dotPos = name.lastIndexOf(".");
+                extension = name.substring(dotPos);
+            }
+        } catch (Exception e) {
+        }
+
+        return extension;
+    }
+
+    public String getFileName(String name) {
+        String fileName = null;
+        try {
+
+            if (name.contains(".")) {
+                int dotPos = name.lastIndexOf(".");
+                fileName = name.substring(0, dotPos);
+            }
+        } catch (Exception e) {
+        }
+
+        return fileName;
+    }
+
+    public void setContents(File aFile, String aContents) throws FileNotFoundException, IOException {
+        if (aFile == null) {
+            throw new IllegalArgumentException("File should not be null.");
+        }
+        if (!aFile.exists()) {
+            throw new FileNotFoundException("File does not exist: " + aFile);
+        }
+        if (!aFile.isFile()) {
+            throw new IllegalArgumentException("Should not be a directory: " + aFile);
+        }
+        if (!aFile.canWrite()) {
+            throw new IllegalArgumentException("File cannot be written: " + aFile);
+        }
+
+        //use buffering
+        Writer output = new BufferedWriter(new FileWriter(aFile));
+        try {
+            //FileWriter always assumes default encoding is OK!
+            output.write(aContents);
+        } finally {
+            output.close();
+        }
+    }
+
+    public void saveFile(File saveToDisk, String content) throws FileNotFoundException, IOException {
+        setContents(saveToDisk, content);
+    }
+    static int spc_count = -1;
+
+    void Process(File aFile) {
+
+        spc_count++;
+        String spcs = "";
+        for (int i = 0; i < spc_count; i++) {
+            spcs += " ";
+        }
+        if (aFile.isFile()) {
+            list.add(aFile.getName());
+            filePath.add(aFile.getPath());
+
+        } else if (aFile.isDirectory()) {
+            File[] listOfFiles = aFile.listFiles();
+
+
+            if (listOfFiles != null) {
+                for (int i = 0; i < listOfFiles.length; i++) {
+                    Process(listOfFiles[i]);
+                }
+            } else {
+            }
+        }
+        spc_count--;
+
+    }
+}
diff --git a/TestON/TAI/src/tai_ofa/OFALoadTree.java b/TestON/TAI/src/tai_ofa/OFALoadTree.java
new file mode 100644
index 0000000..8d1981c
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/OFALoadTree.java
@@ -0,0 +1,178 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package tai_ofa;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.attribute.BasicFileAttributes;
+import javafx.event.Event;
+import javafx.event.EventHandler;
+import javafx.scene.Node;
+import javafx.scene.control.TreeItem;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+
+/**
+ *
+ * @author Raghav Kashyap (raghavkashyap@paxterrasolutions.com)
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+ */
+public class OFALoadTree extends TreeItem<String> {
+
+    OFAFileOperations fileOperation = new OFAFileOperations();
+    public static Image folderCollapseImage = new Image("images/folder.jpg", 30.0, 30.0, true, true);
+    public static Image folderExpandImage = new Image("images/folder.jpg", 10.0, 10.0, true, true);
+    public static Image fileImage = new Image("images/File.png", 30.0, 30.0, true, true);
+    //this stores the full path to the file or directory
+    private String fullPath;
+
+    public String getFullPath() {
+        return (this.fullPath);
+    }
+    private boolean isDirectory;
+
+    public boolean isDirectory() {
+        return (this.isDirectory);
+    }
+
+    public OFALoadTree(Path file) {
+        super(file.toString());
+        this.fullPath = file.toString();
+        //test if this is a directory and set the icon
+        if (Files.isDirectory(file)) {
+            this.isDirectory = true;
+            if ("common".equals(file.getFileName().toString())) {
+                Node rootIcon = new ImageView(new Image(getClass().getResourceAsStream("/images/project.jpeg"), 20, 20, true, true));
+                this.setGraphic(rootIcon);
+            } else if ("cli".equals(file.getFileName().toString())) {
+                Node rootIcon2 = new ImageView(new Image(getClass().getResourceAsStream("/images/terminal.png"), 20, 20, true, true));
+                rootIcon2.setId("/images/terminal.png");
+                this.setGraphic(rootIcon2);
+            } else if ("api".equals(file.getFileName().toString())) {
+                Node rootIcon3 = new ImageView(new Image(getClass().getResourceAsStream("/images/www2.jpg"), 20, 20, true, true));
+                this.setGraphic(rootIcon3);
+            } else if ("emulator".equals(file.getFileName().toString())) {
+                Node rootIcon4 = new ImageView(new Image(getClass().getResourceAsStream("/images/mobile.png"), 20, 20, true, true));
+                this.setGraphic(rootIcon4);
+            } else if ("tool".equals(file.getFileName().toString())) {
+                Node rootIcon5 = new ImageView(new Image(getClass().getResourceAsStream("/images/automatorui.png"), 20, 20, true, true));
+                this.setGraphic(rootIcon5);
+            } else if ("contoller".equals(file.getFileName().toString())) {
+                Node rootIcon6 = new ImageView(new Image(getClass().getResourceAsStream("/images/windows.jpg"), 20, 20, true, true));
+                this.setGraphic(rootIcon6);
+            } else {
+                Node rootIcon = new ImageView(new Image(getClass().getResourceAsStream("/images/project.jpeg"), 20, 20, true, true));
+                rootIcon.setId("/images/project.jpeg");
+                this.setGraphic(rootIcon);
+            }
+        } else {
+            this.isDirectory = false;
+            String fileName = file.getFileName().toString();
+            String ext = fileOperation.getExtension(fileName);
+            if (".ospk".equals(ext)) {
+                Node rootIcon5 = new ImageView(fileImage);
+                rootIcon5.setId(".ospk");
+                this.setGraphic(rootIcon5);
+
+            } else if (".params".equals(ext)) {
+                Node rootIcon1 = new ImageView(new Image(getClass().getResourceAsStream("/images/params.jpeg"), 30, 30, true, true));
+                rootIcon1.setId(".params");
+                setGraphic(rootIcon1);
+
+            } else if (".topo".equals(ext)) {
+                Node rootIcon3 = new ImageView(new Image(getClass().getResourceAsStream("/images/tpl.png"), 30, 30, true, true));
+                rootIcon3.setId(".topo");
+                setGraphic(rootIcon3);
+            } else if (".log".equals(ext)) {
+                Node rootIcon3 = new ImageView(new Image(getClass().getResourceAsStream("/images/log.jpg"), 20, 20, true, true));
+                rootIcon3.setId(".log");
+                setGraphic(rootIcon3);
+            } else if (".rpt".equals(ext)) {
+                Node rootIcon3 = new ImageView(new Image(getClass().getResourceAsStream("/images/report.jpeg"), 20, 20, true, true));
+                rootIcon3.setId(".rpt");
+                setGraphic(rootIcon3);
+            } else if (".session".equals(ext)) {
+                Node rootIcon3 = new ImageView(new Image(getClass().getResourceAsStream("/images/session.png"), 20, 20, true, true));
+                rootIcon3.setId(".session");
+                setGraphic(rootIcon3);
+            } else if (".py".equals(ext)) {
+                Node rootIcon3 = new ImageView(new Image(getClass().getResourceAsStream("/images/py.jpg"), 20, 20, true, true));
+                rootIcon3.setId(".py");
+                setGraphic(rootIcon3);
+            }
+
+            //if you want different icons for different file types this is where you'd do it
+        }
+
+        //set the value
+        if (!fullPath.endsWith(File.separator)) {
+            //set the value (which is what is displayed in the tree)
+            String value = file.toString();
+            int indexOf = value.lastIndexOf(File.separator);
+            if (indexOf > 0) {
+                this.setValue(value.substring(indexOf + 1));
+            } else {
+                this.setValue(value);
+            }
+        }
+
+
+        this.addEventHandler(TreeItem.branchExpandedEvent(), new EventHandler() {
+            @Override
+            public void handle(Event e) {
+                OFALoadTree source = (OFALoadTree) e.getSource();
+                if (source.isDirectory() && source.isExpanded()) {
+                }
+                try {
+                    if (source.getChildren().isEmpty()) {
+                        Path path = Paths.get(source.getFullPath());
+                        BasicFileAttributes attribs = Files.readAttributes(path, BasicFileAttributes.class);
+                        if (attribs.isDirectory()) {
+                            DirectoryStream<Path> dir = Files.newDirectoryStream(path);
+                            for (Path file : dir) {
+                                OFALoadTree treeNode = new OFALoadTree(file);
+                                String fileExtension = fileOperation.getExtension(treeNode.getValue());
+                                String fileName = fileOperation.getFileName(treeNode.getValue());
+                                if (fileExtension == null || fileExtension.equals(".py") || fileExtension.equals(".ospk") || fileExtension.equals(".topo") || fileExtension.equals(".params") || fileExtension.equals(".log") || fileExtension.equals(".rpt") || fileExtension.equals(".session")) {
+                                    if (fileExtension == null) {
+                                        treeNode.setExpanded(true);
+                                        source.getChildren().add(treeNode);
+                                    } else {
+                                        if (fileExtension.matches(".(ospk|params|topo|py|log|rpt|session)")) {
+                                            String finalValue = treeNode.getValue().replace(fileExtension, "");
+                                            treeNode.setValue(finalValue);
+                                            if (!treeNode.getValue().equals("__init__")) {
+                                                source.getChildren().add(treeNode);
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+
+                } catch (Exception ex) {
+                }
+            }
+        });
+    }
+}
diff --git a/TestON/TAI/src/tai_ofa/OFAParamDeviceName.java b/TestON/TAI/src/tai_ofa/OFAParamDeviceName.java
new file mode 100644
index 0000000..a8146df
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/OFAParamDeviceName.java
@@ -0,0 +1,336 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package tai_ofa;
+
+import java.io.BufferedReader;
+import java.io.DataInputStream;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ *
+ * @author Raghav Kashyap (raghavkashyap@paxterrasolutions.com)
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+ */
+class OFAParamDeviceName {
+
+    String paramFilePath;
+    ArrayList<String> paramDeviceName;
+    ArrayList<String> driverFunctionName;
+    ArrayList<String> paramDeviceType;
+    ArrayList<String> paramDeviceCoordinate;
+    ArrayList<String> paramDeviceHost;
+    ArrayList<String> paramDeviceUser;
+    ArrayList<String> paramDevicePassword;
+    ArrayList<String> paramDeviceTransport;
+    ArrayList<String> paramDevicePort;
+    ArrayList<String> paramDeviceBrowser;
+    ArrayList<String> paramDeviceUrl;
+    HashMap<String, String> deviceInfo = new HashMap();
+    HashMap<String, String> urlInfo = new HashMap();
+    HashMap<String, String> browserInfo = new HashMap();
+    HashMap<String, String> coordinateInfo = new HashMap();
+    HashMap<String, String> hostInfo = new HashMap();
+    HashMap<String, String> userInfo = new HashMap();
+    HashMap<String, String> passwordInfo = new HashMap();
+    HashMap<String, String> portInfo = new HashMap();
+    HashMap<String, String> transportInfo = new HashMap();
+    String cliFunction;
+    HashMap deviceFunctionAndParameter = new HashMap();
+    HashMap<String, String> functionWithParameter;
+    String functionName;
+    String functionParameter;
+    HashMap<String, String> webFunctionHashFirstParameter = new HashMap<String, String>();
+    HashMap<String, String> webFunctionHashSecondParameter = new HashMap<String, String>();
+    ArrayList<String> seleniumFunctionList = new ArrayList<String>();
+    String bdrAction;
+    TAILocale label = new TAILocale(new Locale("en", "EN"));
+    String autoMateHarnessPath = label.OFAHarnessPath;
+    ArrayList<String> bdrFunctionName;
+
+    public OFAParamDeviceName() {
+    }
+
+    public OFAParamDeviceName(String filePath, String driverFilePath) {
+        paramDeviceName = new ArrayList<String>();
+        paramDeviceType = new ArrayList<String>();
+        paramDeviceCoordinate = new ArrayList<String>();
+        paramDeviceHost = new ArrayList<String>();
+        paramDeviceUser = new ArrayList<String>();
+        paramDevicePassword = new ArrayList<String>();
+        paramDeviceTransport = new ArrayList<String>();
+        paramDevicePort = new ArrayList<String>();
+        paramDeviceBrowser = new ArrayList<String>();
+        paramDeviceUrl = new ArrayList<String>();
+        this.paramFilePath = filePath;
+    }
+
+    public void parseParamFile() {
+        try {
+
+            FileInputStream fstream = new FileInputStream(paramFilePath);
+            ArrayList<String> paramFileName = new ArrayList<String>();
+            ArrayList<String> nameBetweenTags = new ArrayList<String>();
+            DataInputStream in = new DataInputStream(fstream);
+            BufferedReader br = new BufferedReader(new InputStreamReader(in));
+            String strLine;
+            while ((strLine = br.readLine()) != null) {
+                paramFileName.add(strLine);
+
+            }
+
+            for (int i = 0; i < paramFileName.size(); i++) {
+                String dName = "";
+                String dType = "";
+                String dCoordinate = "";
+                String dHost = "";
+                String dUser = "";
+                String dPassword = "";
+                String dTransport = "";
+                String dPort = "";
+                String dBrowser = "";
+                String dUrl = "";
+                Pattern devicePatternMatch = Pattern.compile("<COMPONENT>");
+                Matcher deviceNameMatch = devicePatternMatch.matcher(paramFileName.get(i));
+                if (deviceNameMatch.find()) {
+                    int j = i + 1;
+                    while (!paramFileName.get(j).equals("</COMPONENT>")) {
+                        Pattern newTag = Pattern.compile("<(.+)(\\d+)>");
+                        Matcher tagMatch = newTag.matcher(paramFileName.get(j));
+                        if (tagMatch.find()) {
+                            String temp = tagMatch.group(1);
+                            Pattern slashCheck = Pattern.compile("^\\w+");
+                            Matcher slashMatch = slashCheck.matcher(temp);
+                            if (slashMatch.find()) {
+                                paramDeviceName.add(slashMatch.group() + tagMatch.group(2));
+                                dName = slashMatch.group() + tagMatch.group(2);
+                            }
+
+                        }
+
+
+                        Pattern deviceTypePattern = Pattern.compile("<type>\\s*(.+)\\s*</type>");
+                        Matcher deviceTypeMatch = deviceTypePattern.matcher(paramFileName.get(j));
+
+                        while (deviceTypeMatch.find()) {
+                            paramDeviceType.add(deviceTypeMatch.group(1));
+                            dType = deviceTypeMatch.group(1).toLowerCase();
+
+                        }
+                        Pattern deviceCoordinatePattern = Pattern.compile("<coordinate(x,y)>\\s*(.+)\\s*</coordinate(x,y)>");
+                        Matcher deviceCoordinateMatch = deviceCoordinatePattern.matcher(paramFileName.get(j));
+                        while (deviceCoordinateMatch.find()) {
+                            paramDeviceCoordinate.add(deviceCoordinateMatch.group(1));
+                            dCoordinate = deviceCoordinateMatch.group(1);
+
+                        }
+                        Pattern devicehostNamePattern = Pattern.compile("<host>\\s*(.+)\\s*</host>");
+                        Matcher deviceHostMatch = devicehostNamePattern.matcher(paramFileName.get(j));
+
+                        while (deviceHostMatch.find()) {
+                            paramDeviceHost.add(deviceHostMatch.group(1));
+                            dHost = deviceHostMatch.group(1);
+                        }
+                        Pattern deviceUserPattern = Pattern.compile("<user>\\s*(.+)\\s*</user>");
+                        Matcher deviceUserMatch = deviceUserPattern.matcher(paramFileName.get(j));
+                        while (deviceUserMatch.find()) {
+                            paramDeviceUser.add(deviceUserMatch.group(1));
+                            dUser = deviceUserMatch.group(1);
+                        }
+
+                        Pattern devicePasswordPattern = Pattern.compile("<password>\\s*(.+)\\s*</password>");
+                        Matcher devicePasswordMatch = devicePasswordPattern.matcher(paramFileName.get(j));
+                        while (devicePasswordMatch.find()) {
+                            paramDevicePassword.add(devicePasswordMatch.group(1));
+                            dPassword = devicePasswordMatch.group(1);
+                        }
+
+                        Pattern devicePortPattern = Pattern.compile("<test_target>\\s*(.+)\\s*</test_target>");
+                        Matcher devicePortMatch = devicePortPattern.matcher(paramFileName.get(j));
+                        while (devicePortMatch.find()) {
+                            paramDevicePort.add(devicePortMatch.group(1));
+                            dPort = devicePortMatch.group(1);
+                        }
+
+                        deviceInfo.put(dName, dType);
+                        coordinateInfo.put(dName, dCoordinate);
+                        hostInfo.put(dName, dHost);
+                        userInfo.put(dName, dUser);
+                        passwordInfo.put(dName, dPassword);
+                        portInfo.put(dName, dPort);
+                        j++;
+                    }
+                }
+            }
+            //Close the input stream
+            in.close();
+        } catch (Exception e) {//Catch exception if any
+            System.err.println("Error: " + e.getMessage());
+        }
+    }
+
+    public void parseDevice(String devicePath) {
+        try {
+            FileInputStream fstream = new FileInputStream(devicePath);
+            DataInputStream in = new DataInputStream(fstream);
+            BufferedReader br = new BufferedReader(new InputStreamReader(in));
+            String strLine;
+            while ((strLine = br.readLine()) != null) {
+                Pattern cliFunctionPattern = Pattern.compile("sub\\s+(\\w+)");
+                Matcher cliFunctionMatch = cliFunctionPattern.matcher(strLine);
+                Pattern cliFunctionArgumentPattern = Pattern.compile("utilities.parse_args\\(\\[\\s+qw\\((.*)\\)\\s*\\]\\,(.*)");
+                Matcher argumentMatch = cliFunctionArgumentPattern.matcher(strLine);
+                while (cliFunctionMatch.find()) {
+                    cliFunction = cliFunctionMatch.group(1);
+                    Pattern rm = Pattern.compile("_(.*)");
+                    Matcher str2 = rm.matcher(cliFunction);
+                    if (!str2.find()) {
+                    }
+                }
+                while (argumentMatch.find()) {
+                    deviceFunctionAndParameter.put(cliFunction, argumentMatch.group(1));
+                }
+            }
+        } catch (Exception e) {
+        }
+    }
+
+    public void driverFunctionName(String driverPath) {
+        try {
+            functionWithParameter = new HashMap<String, String>();
+            FileInputStream fstream = new FileInputStream(driverPath);
+            driverFunctionName = new ArrayList<String>();
+            DataInputStream in = new DataInputStream(fstream);
+            BufferedReader br = new BufferedReader(new InputStreamReader(in));
+            String strLine;
+            while ((strLine = br.readLine()) != null) {
+                Pattern functionParameterPattern = Pattern.compile("(.*)\\s*=\\s*utilities.parse_args\\(\\s*\\[\\s*(.*)\\s*\\]\\s*\\,(.*)");
+                Matcher functionParaMeterMatch = functionParameterPattern.matcher(strLine);
+                Pattern pattern = Pattern.compile("^\\s*def\\s+(\\w+)");
+                Matcher match = pattern.matcher(strLine);
+                while (match.find()) {
+                    functionName = match.group(1);
+                    Pattern cliFunctionWithOut_ = Pattern.compile("_(.*)");
+                    Matcher cliFunctionWithOut_Match = cliFunctionWithOut_.matcher(functionName);
+                    if (!cliFunctionWithOut_Match.find()) {
+                        driverFunctionName.add(match.group(1));
+                    }
+
+
+                }
+                while (functionParaMeterMatch.find()) {
+                    functionParameter = functionParaMeterMatch.group(2);
+                    functionWithParameter.put(functionName, functionParameter);
+                }
+            }
+        } catch (Exception e) {
+        }
+    }
+
+    public ArrayList<String> getParamDeviceName() {
+        return paramDeviceName;
+    }
+
+    public ArrayList<String> getParamDeviceType() {
+        return paramDeviceType;
+    }
+
+    public ArrayList<String> getDriverFunctionName() {
+        return driverFunctionName;
+    }
+
+    public ArrayList<String> getCoordinateName() {
+        return paramDeviceCoordinate;
+    }
+
+    public ArrayList<String> getBrowserName() {
+        return paramDeviceBrowser;
+    }
+
+    public ArrayList<String> getHostName() {
+        return paramDeviceHost;
+    }
+
+    public ArrayList<String> getUserName() {
+        return paramDeviceUser;
+    }
+
+    public ArrayList<String> getPassword() {
+        return paramDevicePassword;
+    }
+
+    public ArrayList<String> getTransport() {
+        return paramDeviceTransport;
+    }
+
+    public ArrayList<String> getPort() {
+        return paramDevicePort;
+    }
+
+    public ArrayList<String> getUrl() {
+        return paramDeviceUrl;
+    }
+
+    public HashMap<String, String> getdeviceNameAndType() {
+        return deviceInfo;
+    }
+
+    public HashMap<String, String> getdeviceNameAndBrowser() {
+        return browserInfo;
+    }
+
+    public HashMap<String, String> getdeviceNameAndUrl() {
+        return urlInfo;
+    }
+
+    public HashMap<String, String> getdeviceNameAndCoordinate() {
+        return coordinateInfo;
+    }
+
+    public HashMap<String, String> getdeviceNameAndHost() {
+        return hostInfo;
+    }
+
+    public HashMap<String, String> getdeviceNameAndUser() {
+        return userInfo;
+    }
+
+    public HashMap<String, String> getdeviceNameAndPassword() {
+        return passwordInfo;
+    }
+
+    public HashMap<String, String> getdeviceNameAndTransport() {
+        return transportInfo;
+    }
+
+    public HashMap<String, String> getdeviceNameAndPort() {
+        return portInfo;
+    }
+
+    public HashMap<String, String> getDeviceFunctionAndArgument() {
+        return deviceFunctionAndParameter;
+    }
+}
diff --git a/TestON/TAI/src/tai_ofa/OFATestCaseSelection.java b/TestON/TAI/src/tai_ofa/OFATestCaseSelection.java
new file mode 100644
index 0000000..d7824d0
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/OFATestCaseSelection.java
@@ -0,0 +1,429 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package tai_ofa;
+
+import java.io.BufferedReader;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javafx.application.Application;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.geometry.Insets;
+import javafx.scene.Scene;
+import javafx.scene.control.Button;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.Label;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableView;
+import javafx.scene.control.cell.PropertyValueFactory;
+import javafx.scene.image.ImageView;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.StackPane;
+import javafx.scene.text.Text;
+import javafx.stage.Stage;
+
+/**
+ *
+ * @author Raghav Kashyap (raghavkashyap@paxterrasolutions.com)
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+ */
+public class OFATestCaseSelection extends Application {
+
+    String driverFile;
+    String paramFileName;
+    String pythonFile;
+    TAILocale label = new TAILocale(Locale.ENGLISH);
+
+    OFATestCaseSelection(String fileName, String paramsFileName) {
+        driverFile = label.hierarchyTestON + "/tests/" + fileName + "/" + fileName + ".ospk";
+        pythonFile = label.hierarchyTestON + "/tests/" + fileName + "/" + fileName + ".py";
+        paramFileName = label.hierarchyTestON + "/tests/" + fileName + "/" + fileName + ".params";
+    }
+    ObservableList<TestCaseSelectionTable> data;
+    ObservableList<String> testSelected;
+    TableView<TestCaseSelectionTable> deviceTable;
+    TableColumn selectCaseColumn;
+    TableColumn testCaseIdColumn;
+    TableColumn testCaseNameColumn;
+    TreeMap<String, String> testCaseIdAndName = new TreeMap<String, String>();
+    String caseId, caseName;
+    GridPane testCaseSelectionGrid = new GridPane();
+    TreeMap<String, String> stepHash = new TreeMap<String, String>();
+    TableColumn stepId, stepName;
+    TableView<TestSelectStepTable> stepTable;
+    ObservableList<TestSelectStepTable> stepData;
+
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+        launch(args);
+    }
+
+    @Override
+    public void start(final Stage primaryStage) {
+        primaryStage.setTitle("TestCase Selection");
+        primaryStage.setResizable(false);
+        testSelected = FXCollections.observableArrayList();
+        stepData = FXCollections.observableArrayList();
+
+        testCaseSelectionGrid.setPadding(new Insets(0, 0, 0, 15));
+        testCaseSelectionGrid.setVgap(10);
+        testCaseSelectionGrid.setHgap(20);
+        final CheckBox selectTestCase = new CheckBox();
+        Label testCaseId = new Label("");
+        Label testCaseName = new Label("");
+
+        stepTable = new TableView<TestSelectStepTable>();
+        deviceTable = new TableView<TestCaseSelectionTable>();
+        data = FXCollections.observableArrayList(new TestCaseSelectionTable(selectTestCase, testCaseId, testCaseName));
+        deviceTable.setMinWidth(430);
+        deviceTable.setMaxHeight(300);
+        testCaseIdColumn = new TableColumn();
+
+        testCaseIdColumn.setCellValueFactory(new PropertyValueFactory<TestCaseSelectionTable, CheckBox>("testCaseCheckBox"));
+        testCaseIdColumn.setMinWidth(90);
+        testCaseIdColumn.setResizable(false);
+        selectCaseColumn = new TableColumn("TestCase Id");
+        selectCaseColumn.setSortable(true);
+        selectCaseColumn.setCellValueFactory(new PropertyValueFactory<TestCaseSelectionTable, Label>("testCaseId"));
+        selectCaseColumn.setMinWidth(130);
+        selectCaseColumn.setResizable(false);
+        testCaseNameColumn = new TableColumn("TestCase Name");
+        testCaseNameColumn.setCellValueFactory(new PropertyValueFactory<TestCaseSelectionTable, Label>("testCaseName"));
+        testCaseNameColumn.setMinWidth(130);
+        testCaseNameColumn.setResizable(false);
+        deviceTable.setItems(data);
+        deviceTable.getColumns().addAll(testCaseIdColumn, selectCaseColumn, testCaseNameColumn);
+        stepTable.setMinWidth(620);
+        stepTable.setMaxHeight(330);
+
+        stepId = new TableColumn("ID");
+        stepId.setCellValueFactory(new PropertyValueFactory<TestSelectStepTable, Label>("testStepId"));
+        stepId.setMinWidth(10);
+        stepId.setResizable(true);
+
+        stepName = new TableColumn("Name");
+        stepName.setCellValueFactory(new PropertyValueFactory<TestSelectStepTable, Label>("testStepName"));
+        stepName.setMinWidth(400);
+        stepName.setResizable(true);
+
+
+        stepTable.getColumns().addAll(stepId, stepName);
+        stepTable.setItems(stepData);
+        driverFunctionName();
+
+        Iterator driverFileIterator = testCaseIdAndName.entrySet().iterator();
+        while (driverFileIterator.hasNext()) {
+            Map.Entry testCaseDetail = (Map.Entry) driverFileIterator.next();
+            final CheckBox selectcase = new CheckBox();
+            final Label id = new Label((String) testCaseDetail.getKey());
+            Label name = new Label((String) testCaseDetail.getValue());
+            selectTestCase.selectedProperty().addListener(new ChangeListener<Boolean>() {
+                @Override
+                public void changed(ObservableValue<? extends Boolean> arg0, Boolean arg1, Boolean arg2) {
+                    selectcase.setSelected(true);
+                    if (selectTestCase.isSelected() == false) {
+                        selectcase.setSelected(false);
+                    }
+                }
+            });
+
+            selectcase.selectedProperty().addListener(new ChangeListener<Boolean>() {
+                @Override
+                public void changed(ObservableValue<? extends Boolean> arg0, Boolean arg1, Boolean arg2) {
+                    if (selectcase.isSelected() == true) {
+                        stepData.clear();
+                        for (int i = 0; i < deviceTable.getItems().size(); i++) {
+                            if (deviceTable.getItems().get(i).testCaseId.getText().equals(id.getText())) {
+                                deviceTable.getSelectionModel().select(i);
+                                Pattern caseNumberPattern = Pattern.compile("CASE\\s*(\\d+)");
+                                Matcher caseNumberMatcher = caseNumberPattern.matcher(deviceTable.getItems().get(i).testCaseId.getText());
+                                String caseNumber = "";
+                                if (caseNumberMatcher.find()) {
+                                    caseNumber = caseNumberMatcher.group(1);
+                                }
+
+                                getTestSteps(caseNumber);
+                                testSelected.add(caseNumber);
+
+                                Iterator entries = stepHash.entrySet().iterator();
+                                while (entries.hasNext()) {
+                                    Map.Entry entry = (Map.Entry) entries.next();
+                                    String key = (String) entry.getKey();
+                                    String value = (String) entry.getValue();
+                                    stepData.add(new TestSelectStepTable(new Label(key), new Label(value)));
+                                }
+
+                                stepTable.setItems(stepData);
+                                stepTable.setVisible(true);
+                                try {
+                                    testCaseSelectionGrid.add(new Text("Test Steps :"), 0, 3);
+                                    testCaseSelectionGrid.add(stepTable, 0, 4);
+                                } catch (Exception e) {
+                                }
+                            }
+                        }
+                    }
+
+                    if (deviceTable.getSelectionModel().getSelectedItem().getTestCaseCheckBox().isSelected() == true) {
+                    }
+                }
+            });
+
+            data.add(new TestCaseSelectionTable(selectcase, id, name));
+            testCaseIdColumn.setCellValueFactory(new PropertyValueFactory<TestCaseSelectionTable, CheckBox>("testCaseCheckBox"));
+            testCaseIdColumn.setMinWidth(50);
+            testCaseIdColumn.setResizable(false);
+
+            selectCaseColumn.setCellValueFactory(new PropertyValueFactory<TestCaseSelectionTable, Label>("testCaseId"));
+            selectCaseColumn.setMinWidth(100);
+            selectCaseColumn.setResizable(false);
+
+            testCaseNameColumn.setCellValueFactory(new PropertyValueFactory<TestCaseSelectionTable, Label>("testCaseName"));
+            testCaseNameColumn.setMinWidth(292);
+            testCaseNameColumn.setResizable(false);
+            deviceTable.setItems(data);
+        }
+
+        testCaseSelectionGrid.add(deviceTable, 0, 1);
+
+        HBox optionButton = new HBox(5);
+        optionButton.setPadding(new Insets(0, 0, 0, 0));
+
+        Button startTest = new Button("Save");
+
+        startTest.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                for (int i = 0; i < deviceTable.getItems().size(); i++) {
+
+                    if (deviceTable.getItems().get(i).testCaseIdCheck.isSelected()) {
+                        deviceTable.getSelectionModel().select(i);
+                    }
+
+                    if (deviceTable.getSelectionModel().getSelectedItem().getTestCaseCheckBox().isSelected() == true) {
+                    }
+                }
+
+                StringBuilder testcases = new StringBuilder();
+                for (String s : testSelected) {
+                    testcases.append(s).append(',');
+                }
+                primaryStage.close();
+            }
+        });
+
+        Button modifyParams = new Button("Modify Params");
+        Button cancelButton = new Button("Cancel");
+        optionButton.getChildren().addAll(new Label("                                    "), startTest, modifyParams, cancelButton);
+        testCaseSelectionGrid.add(optionButton, 0, 5);
+
+        StackPane root = new StackPane();
+        root.getChildren().add(testCaseSelectionGrid);
+        primaryStage.setScene(new Scene(root, 650, 400));
+        primaryStage.show();
+    }
+
+    public void driverFunctionName() {
+        try {
+            FileInputStream fstream = new FileInputStream(driverFile);
+            ArrayList<String> driverFunctionName = new ArrayList<String>();
+            DataInputStream in = new DataInputStream(fstream);
+            BufferedReader br = new BufferedReader(new InputStreamReader(in));
+            String strLine;
+            while ((strLine = br.readLine()) != null) {
+                Pattern casePattern = Pattern.compile("^CASE\\s+(\\d+)");
+                Matcher match = casePattern.matcher(strLine);
+                while (match.find()) {
+                    driverFunctionName.add(match.group());
+                    caseId = match.group();
+                    strLine = br.readLine();
+                    casePattern = Pattern.compile("NAME\\s+(\\\"+(.*)\\\")");
+                    match = casePattern.matcher(strLine);
+                    if (match.find()) {
+                        caseName = match.group(2);
+                    }
+                    testCaseIdAndName.put(caseId, caseName);
+                }
+            }
+        } catch (Exception e) {
+        }
+    }
+
+    public void getParamsUpdate(String testcases) {
+        try {
+            File file = new File(paramFileName);
+            BufferedReader reader = new BufferedReader(new FileReader(file));
+            String line = "", oldtext = "";
+            while ((line = reader.readLine()) != null) {
+                oldtext += line + "\r\n";
+            }
+            reader.close();
+            String newtext = oldtext.replaceAll("<testcases>\\s*(\\d+)</testcases>", "<testcases>" + testcases + "</testcases>");
+            FileWriter writer = new FileWriter(paramFileName);
+            writer.write(newtext);
+            writer.close();
+        } catch (IOException ioe) {
+            ioe.printStackTrace();
+        }
+    }
+
+    public TreeMap getCaseIdAndName() {
+        return testCaseIdAndName;
+    }
+
+    public void getTestSteps(String caseNumber) {
+        OFAFileOperations fileOperation = new OFAFileOperations();
+        int stepCount = 0;
+        String stepCounter = "";
+        BufferedReader input = null;
+        ArrayList<String> contents = new ArrayList<String>();
+        File scriptName = new File(driverFile);
+        if (scriptName.exists()) {
+            try {
+                //use buffering, reading one line at a time
+                //FileReader always assumes default encoding is OK!
+                try {
+                    input = new BufferedReader(new FileReader(scriptName));
+                } catch (Exception e) {
+                }
+
+                try {
+                    String line = null; //not declared within while loop
+                    while ((line = input.readLine()) != null) {
+                        contents.add(line);
+                    }
+                } finally {
+                    try {
+                        input.close();
+                    } catch (Exception e) {
+                    }
+                }
+            } catch (IOException ex) {
+                ex.printStackTrace();
+            }
+
+            for (int i = 0; i < contents.size(); i++) {
+                Pattern casePattern = Pattern.compile("\\s*CASE\\s*(\\d+)\\s*");
+                Matcher caseMatcher = casePattern.matcher(contents.get(i));
+                if (caseMatcher.find()) {
+                    if (caseMatcher.group(1).equals(caseNumber)) {
+                        i++;
+                        Pattern casePatterns = Pattern.compile("\\s*CASE\\s*(\\d+)\\s*");
+                        Matcher caseMatchers = casePatterns.matcher(contents.get(i));
+                        while (!caseMatchers.find() && i < contents.size()) {
+                            Pattern casesPatterns = Pattern.compile("\\s*CASE\\s*(\\d+)\\s*");
+                            Matcher casesMatchers = casesPatterns.matcher(contents.get(i));
+                            if (casesMatchers.find()) {
+                                break;
+                            } else {
+                                Pattern stepPattern = Pattern.compile("\\s*STEP\\s+\"\\s*(.*)\\s*\"\\s*");
+                                Matcher stepMatcher = stepPattern.matcher(contents.get(i));
+                                try {
+                                    if (stepMatcher.find()) {
+                                        stepCount++;
+                                        stepCounter = caseNumber + "." + String.valueOf(stepCount);
+                                        stepHash.put(stepCounter, stepMatcher.group(1));
+                                    }
+                                } catch (Exception e) {
+                                    break;
+                                }
+                                i++;
+                            }
+                        }
+                        i--;
+                    }
+                }
+            }
+        } else {
+            try {
+                //use buffering, reading one line at a time
+                //FileReader always assumes default encoding is OK!
+                try {
+                    input = new BufferedReader(new FileReader(pythonFile));
+                } catch (Exception e) {
+                }
+
+                try {
+                    String line = null; //not declared within while loop
+                    while ((line = input.readLine()) != null) {
+                        contents.add(line);
+                    }
+                } finally {
+                    try {
+                        input.close();
+                    } catch (Exception e) {
+                    }
+                }
+            } catch (IOException ex) {
+                ex.printStackTrace();
+            }
+
+            for (int i = 0; i < contents.size(); i++) {
+                Pattern casePattern = Pattern.compile("\\s*def\\s+CASE(\\d+)\\s*\\(\\s*(.*)\\s*\\)\\s*:\\s*");
+                Matcher caseMatcher = casePattern.matcher(contents.get(i));
+                if (caseMatcher.find()) {
+                    if (caseMatcher.group(1).equals(caseNumber)) {
+                        i++;
+                        Pattern casePatterns = Pattern.compile("\\s*def\\s+CASE(\\d+)\\s*\\(\\s*(.*)\\s*\\)\\s*:\\s*");
+                        Matcher caseMatchers = casePatterns.matcher(contents.get(i));
+                        while (!caseMatchers.find() && i < contents.size()) {
+                            Pattern casesPatterns = Pattern.compile("\\s*def\\s+CASE(\\d+)\\s*\\(\\s*(.*)\\s*\\)\\s*:\\s*");
+                            Matcher casesMatchers = casesPatterns.matcher(contents.get(i));
+                            if (casesMatchers.find()) {
+                                break;
+                            } else {
+                                Pattern stepPattern = Pattern.compile("\\s*main.step\\(\\s*\"\\s*(.*)\\s*\"\\s*\\)\\s*");
+                                Matcher stepMatcher = stepPattern.matcher(contents.get(i));
+                                try {
+                                    if (stepMatcher.find()) {
+                                        stepCount++;
+                                        stepCounter = caseNumber + "." + String.valueOf(stepCount);
+                                        stepHash.put(stepCounter, stepMatcher.group(1));
+                                    }
+                                } catch (Exception e) {
+                                    break;
+                                }
+                                i++;
+                            }
+                        }
+                        i--;
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/TestON/TAI/src/tai_ofa/OFATestParameters.java b/TestON/TAI/src/tai_ofa/OFATestParameters.java
new file mode 100644
index 0000000..91d3193
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/OFATestParameters.java
@@ -0,0 +1,221 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package tai_ofa;
+
+import java.util.Iterator;
+import javafx.application.Application;
+import javafx.application.Platform;
+import javafx.collections.ObservableList;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.geometry.Insets;
+import javafx.scene.Scene;
+import javafx.scene.control.Button;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.Label;
+import javafx.scene.control.TextField;
+import javafx.scene.control.TreeItem;
+import javafx.scene.control.TreeView;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.StackPane;
+import javafx.stage.Stage;
+
+/**
+ *
+ * @author Raghav Kashyap (raghavkashyap@paxterrasolutions.com)
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+ */
+public class OFATestParameters extends Application {
+
+    Stage stage;
+    TAI_OFA ofaReferernce;
+    TreeView<String> projectExplorerTreeView;
+    OFATestSummary testSummaryPop;
+    TreeItem<String> selectetdTest;
+    ObservableList<TreeItem<String>> listProject;
+    ObservableList<TreeItem<String>> paramFile;
+    ComboBox<String> paramList;
+    ComboBox<String> topologyList;
+    String projectToRun;
+    /**
+     * @param args the command line arguments
+     */
+    Button selectTestCase = new Button("Select TestCases");
+    Button startTest = new Button("Start Test");
+    Button cancelButton = new Button("Cancel");
+
+    public void setProjectView(TreeView<String> tree) {
+        projectExplorerTreeView = tree;
+    }
+
+    public OFATestParameters(TAI_OFA ofaReference) {
+        this.ofaReferernce = ofaReference;
+    }
+
+    public void setProjectList(ObservableList<TreeItem<String>> list) {
+        listProject = list;
+    }
+
+    public static void main(String[] args) {
+        launch(args);
+    }
+
+    @Override
+    public void start(Stage primaryStage) {
+        testSummaryPop = new OFATestSummary(ofaReferernce, stage);
+        stage = primaryStage;
+        primaryStage.setTitle("Test ParaMeter");
+        primaryStage.setResizable(false);
+        GridPane testParameterGrid = new GridPane();
+        testParameterGrid.setPadding(new Insets(100, 0, 0, 60));
+        testParameterGrid.setVgap(8);
+        testParameterGrid.setHgap(2);
+
+        selectTestCase.setDisable(true);
+        startTest.setDisable(true);
+        Label projectName = new Label("Test Name :");;
+        testParameterGrid.add(projectName, 0, 1);
+        final ComboBox<String> projectNameList = new ComboBox<String>();
+        projectNameList.setMinWidth(170);
+
+        ObservableList<String> dataForProject = projectNameList.getItems();
+        final Iterator<TreeItem<String>> projectIterator = listProject.iterator();
+        while (projectIterator.hasNext()) {
+            final TreeItem<String> treeItem = projectIterator.next();
+            dataForProject.add(treeItem.getValue());
+            ObservableList<TreeItem<String>> list = treeItem.getChildren();
+            Iterator<TreeItem<String>> it = list.iterator();
+        }
+        projectNameList.setItems(dataForProject);
+        testParameterGrid.add(projectNameList, 1, 1);
+        projectNameList.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent arg0) {
+                final Iterator<TreeItem<String>> projectIterator = listProject.iterator();
+                while (projectIterator.hasNext()) {
+                    final TreeItem<String> treeItem = projectIterator.next();
+                    ObservableList<TreeItem<String>> list = treeItem.getChildren();
+                    if (treeItem.getValue().equalsIgnoreCase(projectNameList.getSelectionModel().getSelectedItem())) {
+                        ObservableList<TreeItem<String>> children = treeItem.getChildren();
+                        final Iterator<TreeItem<String>> testListIterator = children.iterator();
+                        while (testListIterator.hasNext()) {
+                            selectetdTest = testListIterator.next();
+                            paramFile = selectetdTest.getChildren();
+                            if (selectetdTest.getGraphic().getId().equals(".params")) {
+                                paramList.getItems().add(selectetdTest.getValue());
+                            }
+
+                            if (selectetdTest.getGraphic().getId().equals(".topo")) {
+                                topologyList.getItems().add(selectetdTest.getValue());
+                            }
+                            selectTestCase.setDisable(false);
+                            startTest.setDisable(false);
+                        }
+                    }
+                }
+            }
+        });
+
+        Label params = new Label("Params");
+        testParameterGrid.add(params, 0, 3);
+        paramList = new ComboBox<String>();
+        paramList.setMinWidth(170);
+        testParameterGrid.add(paramList, 1, 3);
+
+        Label topology = new Label("Topology");
+        testParameterGrid.add(topology, 0, 4);
+        topologyList = new ComboBox<String>();
+        topologyList.setMinWidth(170);
+        testParameterGrid.add(topologyList, 1, 4);
+
+        Label logFolder = new Label("Log Folder");
+        testParameterGrid.add(logFolder, 0, 5);
+        TextField logFolderPath = new TextField();
+        logFolderPath.setMaxWidth(170);
+        testParameterGrid.add(logFolderPath, 1, 5);
+        Label cliOption = new Label("CLI Options:");
+        testParameterGrid.add(cliOption, 0, 6);
+
+        HBox testDirBox = new HBox(5);
+        CheckBox testDirCheck = new CheckBox("Test Directory");
+        TextField testDirPath = new TextField();
+        testDirPath.setMaxWidth(140);
+        testDirBox.getChildren().addAll(testDirCheck, testDirPath);
+        testParameterGrid.add(testDirBox, 1, 7);
+
+        HBox emailBox = new HBox(5);
+        CheckBox emailIdCheck = new CheckBox("Email Id          ");
+        TextField emailText = new TextField();
+        emailText.setMaxWidth(140);
+        emailBox.getChildren().addAll(emailIdCheck, emailText);
+        testParameterGrid.add(emailBox, 1, 8);
+
+        HBox optionButton = new HBox(5);
+        optionButton.setPadding(new Insets(0, 0, 0, 0));
+        optionButton.getChildren().addAll(selectTestCase, startTest, cancelButton);
+        testParameterGrid.add(optionButton, 1, 11);
+
+        selectTestCase.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent arg0) {
+                String testName = projectNameList.getSelectionModel().getSelectedItem();
+                String paramsFileName = paramList.getSelectionModel().getSelectedItem();
+                OFATestCaseSelection testCasePop = new OFATestCaseSelection(testName, paramsFileName);
+                testCasePop.start(new Stage());
+            }
+        });
+
+        startTest.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent arg0) {
+                testSummaryPop.start(new Stage());
+                Runnable firstRunnable = new Runnable() {
+                    public void run() {
+                        try {
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        }
+                    }
+                };
+
+                Runnable secondRunnable = new Runnable() {
+                    public void run() {
+                        try {
+                            ExecuteTest tail = new ExecuteTest(testSummaryPop.getTable(), testSummaryPop.getData(), testSummaryPop.getChart(),
+                                    testSummaryPop.getFinalSummaryTable(), testSummaryPop.getFinalSummaryData(),
+                                    testSummaryPop.getVieLogsButton(), testSummaryPop.getpieChartData(),
+                                    testSummaryPop.getPassData(), testSummaryPop.getFailData(), testSummaryPop.getAbortData(),
+                                    testSummaryPop.getNoResultData(), projectNameList.getSelectionModel().getSelectedItem().toString(), testSummaryPop.getTextArea("log"), testSummaryPop.getStepTable(), testSummaryPop.getStepData(), testSummaryPop.getTextArea("pox"), testSummaryPop.getTextArea("mininet"), testSummaryPop.getTextArea("flowvisor"));
+                            tail.runTest();
+                        } catch (Exception iex) {
+                        }
+                    }
+                };
+                Platform.runLater(firstRunnable);
+                Platform.runLater(secondRunnable);
+                stage.close();
+            }
+        });
+        StackPane root = new StackPane();
+        root.getChildren().add(testParameterGrid);
+        primaryStage.setScene(new Scene(root, 460, 360));
+        primaryStage.show();
+    }
+}
diff --git a/TestON/TAI/src/tai_ofa/OFATestSummary.java b/TestON/TAI/src/tai_ofa/OFATestSummary.java
new file mode 100644
index 0000000..3a1dc15
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/OFATestSummary.java
@@ -0,0 +1,663 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package tai_ofa;
+
+import com.sun.org.apache.xalan.internal.xsltc.compiler.util.StringStack;
+import java.awt.Color;
+import java.awt.TextArea;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Vector;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javafx.application.Application;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.geometry.Insets;
+import javafx.geometry.Orientation;
+import javafx.scene.Group;
+import javafx.scene.Scene;
+import javafx.scene.chart.PieChart;
+import javafx.scene.control.Button;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.ComboBoxBuilder;
+import javafx.scene.control.Label;
+import javafx.scene.control.Separator;
+import javafx.scene.control.SplitPane;
+import javafx.scene.control.Tab;
+import javafx.scene.control.TabPane;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableView;
+import javafx.scene.control.TextAreaBuilder;
+import javafx.scene.control.TextField;
+import javafx.scene.control.TextFieldBuilder;
+import javafx.scene.control.ToolBar;
+import javafx.scene.control.Tooltip;
+import javafx.scene.control.cell.PropertyValueFactory;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.layout.FlowPane;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Pane;
+import javafx.scene.layout.StackPane;
+import javafx.scene.layout.VBox;
+import javafx.scene.text.Text;
+import javafx.stage.Stage;
+import javafx.stage.WindowEvent;
+import org.apache.xmlrpc.XmlRpcClient;
+import org.apache.xmlrpc.XmlRpcException;
+
+/**
+ *
+ * @author Raghav Kashyap (raghavkashyap@paxterrasolutions.com)
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+ */
+public class OFATestSummary extends Application {
+
+    ObservableList<SummaryTable> data;
+    ObservableList<FinalSummaryTable> summaryData;
+    ObservableList<StepTable> stepData;
+    TableView<SummaryTable> summaryTable;
+    TableView<StepTable> stepTable;
+    PieChart.Data passData = new PieChart.Data("Pass", 0);
+    PieChart.Data failData = new PieChart.Data("Fail", 0);
+    PieChart.Data abortData = new PieChart.Data("Abort", 0);
+    PieChart.Data noResult = new PieChart.Data("No Result", 0);
+    ObservableList<PieChart.Data> pieChartData;
+    TableView<FinalSummaryTable> finalSummaryTable = new TableView<FinalSummaryTable>();
+    TableColumn testCaseIdColumn, testCaseNameColumn;
+    TableColumn testCaseStatusColumn, testCaseStartTimeColumn, testCaseEndTimeColumn;
+    Button viewLogs = new Button("Debug & Console");
+    GridPane buttonPane = new GridPane();
+    TableColumn stepId, stepName, stepStatus;
+    TableColumn summaryItem, information;
+    HashMap<String, String> testCaseIdAndName = new HashMap<String, String>();
+    String caseId, caseName;
+    Stage copyStage;
+    PieChart chart;
+    StackPane rootStack;
+    TAI_OFA ofaReference;
+    Stage paramaterWindow;
+    ComboBox LogBox;
+    TabPane execWindow = new TabPane();
+    Tab debugLog = new Tab("Debug Logs");
+    Tab componentLog = new Tab("Test Log");
+    Tab testSummaryTab = new Tab("Test Summary");
+    Tab dpctlSessionTab = new Tab("FlowVisor1.session");
+    Tab mininetSessionTab = new Tab("Mininet1.session");
+    Tab poxSessionTab = new Tab("POX2.session");
+    TabPane baseTabPane = new TabPane();
+    javafx.scene.control.TextArea debugLogText = TextAreaBuilder.create().build();
+    javafx.scene.control.TextArea compononetLogText = TextAreaBuilder.create().build();
+    javafx.scene.control.TextArea flowVisorSessionText = TextAreaBuilder.create().build();
+    javafx.scene.control.TextArea poxSessionText = TextAreaBuilder.create().build();
+    javafx.scene.control.TextArea mininetSessionText = TextAreaBuilder.create().build();
+    String variableName = "";
+    String command = "";
+    ToolBar quickLauchBar = new ToolBar();
+    Double toolBarHeight;
+    Scene scene;
+    SplitPane baseSplitPane = new SplitPane();
+    TabPane consoleTabPane;
+
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+        launch(args);
+    }
+
+    public OFATestSummary(TAI_OFA ofaReference, Stage paramaterWindow) {
+        this.ofaReference = ofaReference;
+        this.paramaterWindow = paramaterWindow;
+    }
+
+    public void start(Stage primaryStage) {
+        copyStage = primaryStage;
+        primaryStage.setTitle("Test Execution Status");
+        primaryStage.setResizable(false);
+        Group rootGroup = new Group();
+        scene = new Scene(rootGroup, 1020, 920);
+        Pane basePanel = new Pane();
+        HBox baseBox = new HBox();
+        VBox consoleBox = new VBox();
+        VBox buttonBox = new VBox();
+
+        getDebugTab();
+        getToolBar();
+        buttonBox.getChildren().addAll(buttonPane);
+        consoleBox.getChildren().addAll(quickLauchBar, baseTabPane);
+        baseBox.getChildren().addAll(consoleBox);
+        basePanel.getChildren().addAll(baseBox);
+        SplitPane sp = getTestSummary();
+        testSummaryTab.setContent(sp);
+        testSummaryTab.setClosable(false);
+        baseTabPane.getTabs().addAll(testSummaryTab);
+        javafx.scene.control.SingleSelectionModel<Tab> selectionModel = baseTabPane.getSelectionModel();
+        selectionModel.select(testSummaryTab);
+        baseTabPane.prefWidthProperty().bind(scene.widthProperty().subtract(200));
+        baseTabPane.prefHeightProperty().bind(scene.heightProperty().subtract(10));
+        primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
+            @Override
+            public void handle(WindowEvent t) {
+                XmlRpcClient server;
+                try {
+                    server = new XmlRpcClient("http://localhost:9000");
+                    Vector params = new Vector();
+                    params.add(new String("main"));
+                    try {
+                        server.execute("stop", new Vector());
+                    } catch (XmlRpcException ex) {
+                        Logger.getLogger(OFATestSummary.class.getName()).log(Level.SEVERE, null, ex);
+                    } catch (IOException ex) {
+                        Logger.getLogger(OFATestSummary.class.getName()).log(Level.SEVERE, null, ex);
+                    }
+                } catch (MalformedURLException ex) {
+                    Logger.getLogger(OFATestSummary.class.getName()).log(Level.SEVERE, null, ex);
+                }
+            }
+        });
+
+        basePanel.prefHeightProperty().bind(scene.heightProperty());
+        quickLauchBar.prefWidthProperty().bind(scene.widthProperty());
+        quickLauchBar.setMinHeight(scene.heightProperty().get() / 20);
+        toolBarHeight = quickLauchBar.getMinHeight();
+        baseTabPane.prefHeightProperty().bind(scene.heightProperty());
+        baseBox.prefHeightProperty().bind(scene.heightProperty());
+        consoleBox.prefHeightProperty().bind(scene.heightProperty());
+        rootGroup.getChildren().addAll(basePanel);
+        primaryStage.setScene(scene);
+        primaryStage.show();
+
+    }
+
+    public TableView getTable() {
+        return summaryTable;
+    }
+
+    public SplitPane getTestSummary() {
+        GridPane testCaseSummaryTable = new GridPane();
+        testCaseSummaryTable.setPadding(new Insets(10, 0, 0, 10));
+        GridPane finalSummaryPane = new GridPane();
+        finalSummaryPane.setPadding(new Insets(300, 0, 0, 20));
+        GridPane stepSummaryPane = new GridPane();
+        stepSummaryPane.setPadding(new Insets(300, 0, 0, 20));
+
+        CheckBox selectTestCase = new CheckBox();
+        summaryTable = new TableView<SummaryTable>();
+        stepTable = new TableView<StepTable>();
+        summaryTable.setMinWidth(580);
+        summaryTable.setMaxHeight(250);
+        testCaseIdColumn = new TableColumn(ofaReference.label.testSummaryTestCaseId);
+        testCaseIdColumn.setCellValueFactory(new PropertyValueFactory<SummaryTable, Label>("testCaseId"));
+        testCaseIdColumn.setMaxWidth(30);
+        testCaseIdColumn.setResizable(true);
+
+        testCaseNameColumn = new TableColumn(ofaReference.label.testSummaryTestCaseName);
+        testCaseNameColumn.setCellValueFactory(new PropertyValueFactory<SummaryTable, Label>("testCaseName"));
+        testCaseNameColumn.setMinWidth(303);
+        testCaseNameColumn.setResizable(true);
+
+        testCaseStatusColumn = new TableColumn(ofaReference.label.testSummaryExecutionStatus);
+        testCaseStatusColumn.setCellValueFactory(new PropertyValueFactory<SummaryTable, Label>("testCaseStatus"));
+        testCaseStatusColumn.setMinWidth(85);
+        testCaseStatusColumn.setResizable(true);
+
+        testCaseStartTimeColumn = new TableColumn(ofaReference.label.testSummaryStartTest);
+        testCaseStartTimeColumn.setCellValueFactory(new PropertyValueFactory<SummaryTable, Label>("testCaseStartTime"));
+        testCaseStartTimeColumn.setMinWidth(195);
+        testCaseStartTimeColumn.setResizable(true);
+
+        testCaseEndTimeColumn = new TableColumn(ofaReference.label.testSummaryEndTest);
+        testCaseEndTimeColumn.setCellValueFactory(new PropertyValueFactory<SummaryTable, Label>("testCaseEndTime"));
+        testCaseEndTimeColumn.setMinWidth(195);
+        testCaseEndTimeColumn.setResizable(true);
+
+        summaryTable.setItems(data);
+        summaryTable.getColumns().addAll(testCaseIdColumn, testCaseNameColumn, testCaseStatusColumn, testCaseStartTimeColumn, testCaseEndTimeColumn);
+
+        summaryItem = new TableColumn(ofaReference.label.summary);
+        summaryItem.setCellValueFactory(new PropertyValueFactory<SummaryTable, Label>("summaryItem"));
+        summaryItem.setMinWidth(140);
+        summaryItem.setResizable(true);
+
+        information = new TableColumn(ofaReference.label.information);
+        information.setCellValueFactory(new PropertyValueFactory<SummaryTable, Label>("information"));
+        information.setMinWidth(210);
+        information.setResizable(true);
+
+        finalSummaryTable.setMinWidth(350);
+        finalSummaryTable.setMaxHeight(300);
+        SplitPane leftPane = new SplitPane();
+        SplitPane rightPane = new SplitPane();
+        leftPane.setOrientation(Orientation.HORIZONTAL);
+        rightPane.setOrientation(Orientation.VERTICAL);
+        finalSummaryTable.setItems(summaryData);
+        finalSummaryTable.setVisible(false);
+        finalSummaryTable.getColumns().addAll(summaryItem, information);
+        HBox pieChart = new HBox(10);
+        pieChart.setPadding(new Insets(300, 0, 0, 300));
+        ArrayList<PieChart.Data> dataList = new ArrayList<PieChart.Data>();
+
+        dataList.add(passData);
+        dataList.add(failData);
+        dataList.add(abortData);
+        dataList.add(noResult);
+        pieChartData = FXCollections.observableArrayList(dataList);
+        chart = new PieChart(pieChartData);
+        chart.setTitle(ofaReference.label.testSummaryTestSummary);
+        pieChart.getChildren().add(chart);
+        chart.setVisible(false);
+        summaryTable.setVisible(false);
+        stepTable.setVisible(true);
+        stepTable.setMinWidth(450);
+        stepTable.setMaxHeight(300);
+
+        stepId = new TableColumn("ID");
+        stepId.setCellValueFactory(new PropertyValueFactory<StepTable, Label>("testStepId"));
+        stepId.setMinWidth(10);
+        stepId.setResizable(true);
+
+        stepName = new TableColumn("Name");
+        stepName.setCellValueFactory(new PropertyValueFactory<StepTable, Label>("testStepName"));
+        stepName.setMinWidth(470);
+        stepName.setResizable(true);
+
+        stepStatus = new TableColumn("Status");
+        stepStatus.setCellValueFactory(new PropertyValueFactory<StepTable, Label>("testStepStatus"));
+        stepStatus.setMinWidth(40);
+        stepStatus.setResizable(true);
+        stepTable.getColumns().addAll(stepId, stepName, stepStatus);
+        stepTable.setItems(stepData);
+        stepSummaryPane.add(stepTable, 0, 2);
+
+        finalSummaryPane.add(finalSummaryTable, 0, 2);
+        rootStack = new StackPane();
+        testCaseSummaryTable.add(summaryTable, 0, 1);
+        rootStack.getChildren().addAll(testCaseSummaryTable, pieChart, stepSummaryPane, finalSummaryPane);
+        leftPane.getItems().addAll(rootStack);
+        consoleTabPane = new TabPane();
+        consoleTabPane.setPrefWidth(700);
+        consoleTabPane.getTabs().addAll(componentLog, debugLog, dpctlSessionTab, mininetSessionTab, poxSessionTab);
+
+        Image topoImage = new Image("images/topo.png", 400, 200, true, true);
+        ImageView topo = new ImageView(topoImage);
+        TabPane imageTabPane = new TabPane();
+        Tab imageTab = new Tab("Test Topology");
+        imageTab.setContent(topo);
+        imageTabPane.getTabs().add(imageTab);
+        imageTabPane.setMinWidth(300);
+        rightPane.getItems().addAll(imageTabPane, consoleTabPane);
+        rightPane.setDividerPosition(1, 400);
+        baseSplitPane.setDividerPosition(1, 10);
+        baseSplitPane.getItems().addAll(leftPane, rightPane);
+        return baseSplitPane;
+    }
+
+    public void getDebugTab() {
+        poxSessionText.prefWidth(450);
+        poxSessionText.prefHeight(620);
+        poxSessionText.setStyle(
+                "-fx-text-fill: #0A0A2A;"
+                + "-fx-background-color: #EFFBFB;");
+        poxSessionText.setEditable(false);
+        poxSessionTab.setContent(poxSessionText);
+        flowVisorSessionText.prefWidth(450);
+        flowVisorSessionText.prefHeight(620);
+        flowVisorSessionText.setStyle(
+                "-fx-text-fill: #0A0A2A;"
+                + "-fx-background-color: #EFFBFB;");
+        flowVisorSessionText.setEditable(false);
+        dpctlSessionTab.setContent(flowVisorSessionText);
+        mininetSessionText.prefWidth(450);
+        mininetSessionText.prefHeight(620);
+        mininetSessionText.setStyle(
+                "-fx-text-fill: #0A0A2A;"
+                + "-fx-background-color: #EFFBFB;");
+        mininetSessionText.setEditable(false);
+        mininetSessionTab.setContent(mininetSessionText);
+        debugLogText.prefWidth(450);
+        debugLogText.prefHeight(620);
+        debugLogText.setStyle(
+                "-fx-text-fill: #0A0A2A;"
+                + "-fx-background-color: #EFFBFB;");
+        debugLogText.setEditable(false);
+        componentLog.setClosable(false);
+        compononetLogText.prefWidth(350);
+        compononetLogText.prefHeight(620);
+        compononetLogText.setStyle(
+                "-fx-text-fill: #0A0A2A;"
+                + "-fx-background-color: #EFFBFB;");
+        compononetLogText.setEditable(false);
+        componentLog.setContent(compononetLogText);
+        debugLog.setClosable(false);
+        debugLog.setContent(debugLogText);
+        debugLog.setContent(debugLogText);
+    }
+
+    public void getToolBar() {
+        Image pauseImage = new Image("images/Pause.png", 20.0, 20.0, true, true);
+        Button pause = new Button("", new ImageView(pauseImage));
+        Image stopImage = new Image("images/Stop.png", 20.0, 20.0, true, true);
+        Button stop = new Button("", new ImageView(stopImage));
+        stop.setTooltip(new Tooltip("Stop"));
+
+        Image resumeImage = new Image("images/Resume_1.png", 20.0, 20.0, true, true);
+        Button resume = new Button("", new ImageView(resumeImage));
+        resume.setTooltip(new Tooltip("Resume"));
+
+        Image dumpVarImage = new Image("images/dumpvar.png", 20.0, 20.0, true, true);
+        Button dumpVar = new Button("", new ImageView(dumpVarImage));
+        dumpVar.setTooltip(new Tooltip("Dump Var"));
+
+        Image showlogImage = new Image("images/showlog.jpg", 20.0, 20.0, true, true);
+        Button showlog = new Button("", new ImageView(showlogImage));
+        showlog.setTooltip(new Tooltip("Show Log"));
+
+        Image currentCaseImage = new Image("images/currentcase.jpg", 20.0, 20.0, true, true);
+        Button currentcase = new Button("", new ImageView(currentCaseImage));
+        currentcase.setTooltip(new Tooltip("Current Case"));
+
+        Image currentStepImage = new Image("images/currentstep.png", 20.0, 20.0, true, true);
+        Button currentStep = new Button("", new ImageView(currentStepImage));
+        currentStep.setTooltip(new Tooltip("Current Step"));
+
+        Image nextStepImage = new Image("images/nextStep.jpg", 20.0, 20.0, true, true);
+        Button nextStep = new Button("", new ImageView(nextStepImage));
+        nextStep.setTooltip(new Tooltip("Next Step"));
+
+        Image compileImage = new Image("images/compile.jpg", 20.0, 20.0, true, true);
+        Button compile = new Button("", new ImageView(compileImage));
+        compile.setTooltip(new Tooltip("Compile"));
+
+        Image getTestImage = new Image("images/testname.jpg", 20.0, 20.0, true, true);
+        Button getTest = new Button("", new ImageView(getTestImage));
+        getTest.setTooltip(new Tooltip("Get Test"));
+
+        Image interpretImage = new Image("images/interpreter.jpg", 20.0, 20.0, true, true);
+        Button interpret = new Button("", new ImageView(interpretImage));
+        interpret.setTooltip(new Tooltip("Interpret"));
+
+        Image doImage = new Image("images/do.jpg", 20.0, 20.0, true, true);
+        Button doCommand = new Button("", new ImageView(doImage));
+        doCommand.setTooltip(new Tooltip("Do"));
+
+        Image redoImage = new Image("images/redo.png", 20.0, 20.0, true, true);
+        Button redoCommand = new Button("", new ImageView(redoImage));
+        redoCommand.setTooltip(new Tooltip("Re-execute"));
+
+        final Button submit = new Button("Enter");
+        final TextField value = TextFieldBuilder.create().build();
+        value.setMinWidth(480);
+        final ExecutionConsole execConsole = new ExecutionConsole(command, submit, value);
+
+        redoCommand.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                requestServer("redo", new Vector());
+                requestServer("resume", new Vector());
+            }
+        });
+
+        getTest.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                requestServer("getTest", new Vector());
+            }
+        });
+
+        doCommand.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                try {
+                    command = "doCommand";
+                    execConsole.start(new Stage());
+                    execConsole.setTitles("do Command");
+                } catch (Exception ex) {
+                    Logger.getLogger(OFATestSummary.class.getName()).log(Level.SEVERE, null, ex);
+                }
+            }
+        });
+
+        interpret.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                try {
+                    value.setEditable(true);
+                    command = "interpret";
+                    execConsole.start(new Stage());
+                    execConsole.setTitles("interpret Command");
+                } catch (Exception ex) {
+                    Logger.getLogger(OFATestSummary.class.getName()).log(Level.SEVERE, null, ex);
+                }
+            }
+        });
+
+        compile.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                try {
+                    command = "doCompile";
+                    execConsole.start(new Stage());
+                    execConsole.setTitles("compile Command");
+                } catch (Exception ex) {
+                    Logger.getLogger(OFATestSummary.class.getName()).log(Level.SEVERE, null, ex);
+                }
+            }
+        });
+
+        resume.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                requestServer("resume", new Vector());
+            }
+        });
+
+        nextStep.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                requestServer("nextStep", new Vector());
+            }
+        });
+
+        currentStep.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                requestServer("currentStep", new Vector());
+            }
+        });
+
+        currentcase.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                requestServer("currentCase", new Vector());
+            }
+        });
+
+        showlog.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                requestServer("showLog", new Vector());
+            }
+        });
+
+        submit.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                variableName = value.getText();
+                execConsole.closeWindow();
+                Vector params = new Vector();
+                params.add(variableName);
+                requestServer(command, params);
+            }
+        });
+        dumpVar.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                try {
+                    command = "dumpVar";
+                    execConsole.start(new Stage());
+                    execConsole.setTitles("dumpvar Command");
+                } catch (Exception ex) {
+                    Logger.getLogger(OFATestSummary.class.getName()).log(Level.SEVERE, null, ex);
+                }
+
+
+            }
+        });
+
+        pause.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                XmlRpcClient server;
+                try {
+                    server = new XmlRpcClient("http://localhost:9000");
+                    try {
+                        Object response = server.execute("pauseTest", new Vector());
+                        compononetLogText.appendText("\n Will pause the test's execution, after completion of this step.....\n\n");
+                    } catch (XmlRpcException ex) {
+                        Logger.getLogger(OFATestSummary.class.getName()).log(Level.SEVERE, null, ex);
+                    } catch (IOException ex) {
+                        Logger.getLogger(OFATestSummary.class.getName()).log(Level.SEVERE, null, ex);
+                    }
+                } catch (MalformedURLException ex) {
+                    Logger.getLogger(OFATestSummary.class.getName()).log(Level.SEVERE, null, ex);
+                }
+            }
+        });
+
+        stop.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                XmlRpcClient server;
+                try {
+                    server = new XmlRpcClient("http://localhost:9000");
+                    Vector params = new Vector();
+                    try {
+                        server.execute("stop", new Vector());
+                    } catch (XmlRpcException ex) {
+                        Logger.getLogger(OFATestSummary.class.getName()).log(Level.SEVERE, null, ex);
+                    } catch (IOException ex) {
+                        Logger.getLogger(OFATestSummary.class.getName()).log(Level.SEVERE, null, ex);
+                    }
+                } catch (MalformedURLException ex) {
+                    Logger.getLogger(OFATestSummary.class.getName()).log(Level.SEVERE, null, ex);
+                }
+            }
+        });
+
+        quickLauchBar.getItems().addAll(pause, resume, stop, new Separator(Orientation.VERTICAL), dumpVar, currentcase, currentStep, showlog, nextStep,
+                new Separator(Orientation.VERTICAL), getTest, compile, doCommand, interpret, redoCommand);
+    }
+
+    public void requestServer(String request, Vector params) {
+
+        XmlRpcClient server;
+        try {
+            server = new XmlRpcClient("http://localhost:9000");
+            try {
+                Object response = server.execute(request, params);
+                javafx.scene.control.SingleSelectionModel<Tab> selectionModel = consoleTabPane.getSelectionModel();
+                selectionModel.select(debugLog);
+                debugLogText.appendText(request + " Ouput \n =====================================================================\n");
+                debugLogText.appendText(response.toString());
+                debugLogText.appendText("\n ======================================================================\n");
+            } catch (XmlRpcException ex) {
+                Logger.getLogger(OFATestSummary.class.getName()).log(Level.SEVERE, null, ex);
+            } catch (IOException ex) {
+                Logger.getLogger(OFATestSummary.class.getName()).log(Level.SEVERE, null, ex);
+            }
+        } catch (MalformedURLException ex) {
+            Logger.getLogger(OFATestSummary.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+
+    public Button getVieLogsButton() {
+        return viewLogs;
+    }
+
+    public StackPane getRoot() {
+        return rootStack;
+    }
+
+    public ObservableList<SummaryTable> getData() {
+        return data;
+    }
+
+    public PieChart getChart() {
+        return chart;
+    }
+
+    public TableView getFinalSummaryTable() {
+        return finalSummaryTable;
+    }
+
+    public ObservableList<FinalSummaryTable> getFinalSummaryData() {
+        return summaryData;
+    }
+
+    public ObservableList<PieChart.Data> getpieChartData() {
+        return pieChartData;
+    }
+
+    public javafx.scene.control.TextArea getTextArea(String name) {
+        if (name.equals("log")) {
+            return compononetLogText;
+        } else if (name.equals("pox")) {
+            return poxSessionText;
+        } else if (name.equals("flowvisor")) {
+            return flowVisorSessionText;
+        } else if (name.equals("mininet")) {
+            return mininetSessionText;
+        }
+        return new javafx.scene.control.TextArea();
+    }
+
+    public PieChart.Data getPassData() {
+        return passData;
+    }
+
+    public PieChart.Data getFailData() {
+        return failData;
+    }
+
+    public PieChart.Data getAbortData() {
+        return abortData;
+    }
+
+    public PieChart.Data getNoResultData() {
+        return noResult;
+    }
+
+    ///Step TABLE 
+    public TableView getStepTable() {
+        return stepTable;
+    }
+
+    public ObservableList<StepTable> getStepData() {
+        return stepData;
+    }
+}
diff --git a/TestON/TAI/src/tai_ofa/OFATopology.java b/TestON/TAI/src/tai_ofa/OFATopology.java
new file mode 100644
index 0000000..b2e6830
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/OFATopology.java
@@ -0,0 +1,278 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package tai_ofa;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Locale;
+import javafx.application.Application;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.event.Event;
+import javafx.event.EventHandler;
+import javafx.geometry.Insets;
+import javafx.scene.Scene;
+import javafx.scene.control.Button;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.Label;
+import javafx.scene.control.PasswordField;
+import javafx.scene.control.RadioButton;
+import javafx.scene.control.Tab;
+import javafx.scene.control.TabPane;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableColumn.CellEditEvent;
+import javafx.scene.control.TableView;
+import javafx.scene.control.TextField;
+import javafx.scene.control.TextFieldBuilder;
+import javafx.scene.control.cell.PropertyValueFactory;
+import javafx.scene.control.cell.TextFieldTableCell;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Pane;
+import javafx.stage.Stage;
+import sun.misc.Cleaner;
+
+/**
+ *
+ * @author Raghav Kashyap (raghavkashyap@paxterrasolutions.com)
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+ */
+public class OFATopology extends Application {
+
+    public OFATopology() {
+    }
+    ObservableList<OFATopologyInterface> data;
+    TableView<OFATopologyInterface> deviceTable;
+    TableColumn device;
+    TableColumn number;
+    TableColumn type;
+    int count = 1;
+    String getHostName, getUserName, getPassword, getTranportProtocol, getPort;
+    ArrayList<String> getAttribute = new ArrayList<String>();
+    ArrayList<String> getValue = new ArrayList<String>();
+    ArrayList<TextField> attributeList = new ArrayList<TextField>();
+    ArrayList<TextField> valueList = new ArrayList<TextField>();
+    TextField attributeText;
+    Button interFacesave;
+    TextField valueText;
+    Button save;
+    TextField hostNameText;
+    TextField userNameText;
+    PasswordField passwordText;
+    TextField portText;
+    TextField deviceText;
+    ComboBox<String> transportList;
+    Stage copyStage;
+    ArrayList<String> propertyDetail = new ArrayList<String>();
+    HashMap<TextField, TextField> hashProperty = new HashMap<TextField, TextField>();
+    Button defaultButton;
+    Button cancelButton;
+    RadioButton testTargetRadioButton;
+    TAILocale label = new TAILocale(new Locale("en", "EN"));
+
+    /**
+     * @param args the command line arguments
+     */
+    OFATopology(TextField text) {
+        deviceText = text;
+    }
+
+    @Override
+    public void start(final Stage primaryStage) {
+        copyStage = primaryStage;
+        primaryStage.setTitle(label.topoTitle);
+        primaryStage.setResizable(false);
+        TabPane toplogyTabPane = new TabPane();
+        toplogyTabPane.setMaxHeight(280);
+        Tab propertyTab = new Tab(label.topoProperties);
+        Tab interfaceTab = new Tab("Component");
+        propertyTab.setClosable(false);
+        interfaceTab.setClosable(false);
+        toplogyTabPane.getTabs().addAll(propertyTab, interfaceTab);
+
+        GridPane propertyGrid = new GridPane();
+        propertyGrid.setVgap(8);
+        propertyGrid.setHgap(10);
+        propertyGrid.setPadding(new Insets(10, 0, 0, 50));
+
+        Label attribute = new Label(label.topoAttribute);
+        attribute.setStyle("-fx-padding: 0; -fx-background-color: lightgray; -fx-border-width: 2;-fx-border-color: gray;");
+        propertyGrid.add(attribute, 0, 1);
+
+        Label value = new Label(label.topoValue);
+        value.setStyle("-fx-padding: 0; -fx-background-color: lightgray; -fx-border-width: 2;-fx-border-color: gray;");
+        propertyGrid.add(value, 1, 1);
+
+        Label hostName = new Label(label.topoHost);
+        propertyGrid.add(hostName, 0, 2);
+        hostNameText = new TextField();
+        propertyGrid.add(hostNameText, 1, 2);
+        Label userName = new Label(label.topoUserName);
+        propertyGrid.add(userName, 0, 3);
+        userNameText = new TextField();
+        propertyGrid.add(userNameText, 1, 3);
+        Label password = new Label(label.topoPassword);
+        propertyGrid.add(password, 0, 4);
+        passwordText = new PasswordField();
+        propertyGrid.add(passwordText, 1, 4);
+        Label transport = new Label(label.topoTransport);
+        transportList = new ComboBox<String>();
+        transportList.setMinWidth(200);
+        transportList.getItems().addAll(label.topoSSH, label.topoTELNET, label.topoFTP, label.topoRLOGIN);
+        Label testTargetLabel = new Label("Test Target");
+        propertyGrid.add(testTargetLabel, 0, 5);
+        testTargetRadioButton = new RadioButton("True");
+        propertyGrid.add(testTargetRadioButton, 1, 5);
+        HBox propertyButton = new HBox(5);
+
+        propertyButton.setPadding(new Insets(280, 0, 0, 140));
+        save = new Button(label.topoSave);
+        defaultButton = new Button(label.topoDefault);
+        cancelButton = new Button(label.topoCancel);
+        propertyButton.getChildren().addAll(save, defaultButton, cancelButton);
+        propertyTab.setContent(propertyGrid);
+
+        //  interface tab code 
+        GridPane interfaceGridPane = new GridPane();
+        interfaceGridPane.setVgap(20);
+        interfaceGridPane.setHgap(20);
+        interfaceGridPane.setPadding(new Insets(10, 0, 0, 10));
+        Label interFaceNumber = new Label("" + count);
+        attributeText = new TextField();
+        valueText = new TextField();
+
+        valueText.setOnKeyPressed(new EventHandler<KeyEvent>() {
+            @Override
+            public void handle(KeyEvent keyEvent) {
+                if (keyEvent.getCode() == KeyCode.ENTER) {
+                    deviceTable.getSelectionModel().select(deviceTable.getItems().size() - 1);
+                    if (deviceTable.getSelectionModel().isSelected(deviceTable.getItems().size() - 1)) {
+                        if (!deviceTable.getSelectionModel().getSelectedItem().getDeviceName().getText().equals("") && !deviceTable.getSelectionModel().getSelectedItem().getDeviceType().getText().equals("")) {
+                            addInterFace();
+                        }
+                    }
+                }
+            }
+        });
+
+        deviceTable = new TableView<OFATopologyInterface>();
+        data = FXCollections.observableArrayList(new OFATopologyInterface(interFaceNumber, attributeText, valueText));
+        deviceTable.setMinWidth(330);
+        deviceTable.setMaxHeight(200);
+        number = new TableColumn(label.topoInterfaces);
+        number.setCellValueFactory(new PropertyValueFactory<OFATopologyInterface, Label>("interFaceNumber"));
+        number.setMinWidth(90);
+        number.setResizable(false);
+        device = new TableColumn(label.topoAttribute);
+        device.setCellValueFactory(new PropertyValueFactory<OFATopologyInterface, TextField>("deviceName"));
+        device.setMaxWidth(119);
+        device.setResizable(false);
+        type = new TableColumn(label.topoValues);
+        type.setCellValueFactory(new PropertyValueFactory<OFATopologyInterface, TextField>("deviceType"));
+        type.setMaxWidth(119);
+        type.setResizable(false);
+        deviceTable.setItems(data);
+        deviceTable.getColumns().addAll(number, device, type);
+        interfaceGridPane.add(deviceTable, 0, 1);
+        interfaceTab.setContent(interfaceGridPane);
+        HBox interFaceButton = new HBox(5);
+        interFaceButton.setPadding(new Insets(0, 0, 0, 2));
+        attributeList.add(attributeText);
+        valueList.add(valueText);
+        hashProperty.put(attributeText, valueText);
+
+        interfaceGridPane.add(interFaceButton, 0, 2);
+        Pane root = new Pane();
+        root.getChildren().addAll(propertyButton, toplogyTabPane);
+        primaryStage.setScene(new Scene(root, 350, 300));
+        primaryStage.show();
+    }
+
+    public void addInterFace() {
+        int intNumber = ++count;
+        Label interFaceNumber = new Label("" + intNumber);
+        attributeText = new TextField();
+        attributeList.add(attributeText);
+        valueText = new TextField();
+        attributeText.setMaxWidth(120);
+        valueText.setMinWidth(120);
+        hashProperty.put(attributeText, valueText);
+        for (int i = 0; i < deviceTable.getItems().size(); i++) {
+            deviceTable.getSelectionModel().select(deviceTable.getItems().size() - 1);
+        }
+
+        deviceTable.getSelectionModel().select(deviceTable.getItems().size());
+        valueText.setOnKeyPressed(new EventHandler<KeyEvent>() {
+            @Override
+            public void handle(KeyEvent keyEvent) {
+                if (keyEvent.getCode() == KeyCode.ENTER) {
+                    deviceTable.getSelectionModel().select(deviceTable.getItems().size() - 1);
+                    if (deviceTable.getSelectionModel().isSelected(deviceTable.getItems().size() - 1)) {
+                        if (!deviceTable.getSelectionModel().getSelectedItem().getDeviceName().getText().equals("") && !deviceTable.getSelectionModel().getSelectedItem().getDeviceType().getText().equals("")) {
+                            addInterFace();
+                        }
+                    }
+
+                }
+            }
+        });
+        valueList.add(valueText);
+        data.add(new OFATopologyInterface(interFaceNumber, attributeText, valueText));
+        number.setCellValueFactory(new PropertyValueFactory<OFATopologyInterface, Label>("interFaceNumber"));
+        number.setMinWidth(90);
+        number.setResizable(false);
+        device.setCellValueFactory(new PropertyValueFactory<OFATopologyInterface, TextField>("deviceName"));
+        device.setMaxWidth(120);
+        device.setResizable(false);
+        type.setCellValueFactory(new PropertyValueFactory<OFATopologyInterface, TextField>("deviceType"));
+        type.setMaxWidth(120);
+        type.setResizable(false);
+        deviceTable.setItems(data);
+        deviceTable.setEditable(true);
+    }
+
+    public String getHostName() {
+        return getHostName;
+    }
+
+    public String getUserName() {
+        return getUserName;
+    }
+
+    public String getPassword() {
+        return getPassword;
+    }
+
+    public String getTransportProtocool() {
+        return getTranportProtocol;
+    }
+
+    public String getPort() {
+        return getPort;
+    }
+
+    public ArrayList getAtttribute() {
+        return getAttribute;
+    }
+
+    public ArrayList getValue() {
+        return getValue;
+    }
+}
diff --git a/TestON/TAI/src/tai_ofa/OFATopologyInterface.java b/TestON/TAI/src/tai_ofa/OFATopologyInterface.java
new file mode 100644
index 0000000..085a64f
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/OFATopologyInterface.java
@@ -0,0 +1,64 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package tai_ofa;
+
+import javafx.scene.control.Label;
+import javafx.scene.control.TextField;
+
+/**
+ *
+ * @author Raghav Kashyap (raghavkashyap@paxterrasolutions.com)
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+ */
+public class OFATopologyInterface {
+    public Label interFaceNumber; 
+    private TextField deviceName;
+    private  TextField deviceType;
+     
+
+    
+    public OFATopologyInterface(Label emailtext,TextField deviceNameText,TextField deviceTypeText){
+            this.deviceName = deviceNameText;
+            this.deviceType = deviceTypeText;
+            this.interFaceNumber = emailtext;
+    }
+     
+        public TextField getDeviceName() {
+            return deviceName;
+        }
+        public void setDeviceName(TextField fName) {
+            deviceName = fName;
+        }
+        
+        public TextField getDeviceType() {
+            return deviceType;
+        }
+        public void setDeviceType(TextField fName) {
+            deviceType = fName;
+        }
+        
+        public Label getInterFaceNumber() {
+            return interFaceNumber;
+        }
+        public void setInterFaceNumber(Label fName) {
+            interFaceNumber = fName;
+        }
+}
+
+    
+
diff --git a/TestON/TAI/src/tai_ofa/OFATopologyLink.java b/TestON/TAI/src/tai_ofa/OFATopologyLink.java
new file mode 100644
index 0000000..8efe264
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/OFATopologyLink.java
@@ -0,0 +1,128 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package tai_ofa;
+
+import javafx.application.Application;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.geometry.Insets;
+import javafx.scene.Scene;
+import javafx.scene.control.Button;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.Label;
+import javafx.scene.control.TextField;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.StackPane;
+import javafx.stage.Stage;
+
+/**
+ *
+ * @author Raghav Kashyap (raghavkashyap@paxterrasolutions.com)
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+ */
+class OFATopologyLink extends Application {
+
+    Label device1;
+    ComboBox<String> devicesInTopoEditor;
+    ComboBox<String> destDevicesInTopoEditor;
+    ComboBox<String> interfaceList2;
+    ComboBox<String> interfaceList4;
+    GridPane propertyGrid = new GridPane();
+    Button finishSelectedLink;
+    Button cancelButton;
+    TextField nameText;
+    TextField typeText;
+    Stage copyStage;
+
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+        launch(args);
+    }
+
+    @Override
+    public void start(final Stage primaryStage) {
+        copyStage = primaryStage;
+        primaryStage.setTitle("Selected Link Popup");
+        propertyGrid.setVgap(8);
+        propertyGrid.setHgap(30);
+        primaryStage.setResizable(false);
+        propertyGrid.setPadding(new Insets(10, 0, 0, 50));
+        devicesInTopoEditor = new ComboBox<String>();
+        interfaceList2 = new ComboBox<String>();
+        Label attribute = new Label("Attribute");
+        attribute.setStyle("-fx-padding: 0; -fx-background-color: lightgray; -fx-border-width: 2;-fx-border-color: gray;");
+        propertyGrid.add(attribute, 0, 1);
+
+        Label value = new Label("Value");
+        value.setStyle("-fx-padding: 0; -fx-background-color: lightgray; -fx-border-width: 2;-fx-border-color: gray;");
+        propertyGrid.add(value, 1, 1);
+        Label name = new Label("Name");
+        propertyGrid.add(name, 0, 2);
+        nameText = new TextField();
+        propertyGrid.add(nameText, 1, 2);
+
+        Label type = new Label("Type");
+        propertyGrid.add(type, 0, 3);
+        typeText = new TextField();
+        propertyGrid.add(typeText, 1, 3);
+        device1 = new Label("Source Device");
+        propertyGrid.add(device1, 0, 4);
+        devicesInTopoEditor.setMinWidth(170);
+        propertyGrid.add(devicesInTopoEditor, 1, 4);
+
+        Label interface1 = new Label("Interface");
+        propertyGrid.add(interface1, 0, 5);
+        interfaceList2 = new ComboBox<String>();
+        interfaceList2.setMinWidth(170);
+        propertyGrid.add(interfaceList2, 1, 5);
+
+        Label device2 = new Label("Destination Device");
+        propertyGrid.add(device2, 0, 6);
+        destDevicesInTopoEditor = new ComboBox<String>();
+        destDevicesInTopoEditor.setMinWidth(170);
+        propertyGrid.add(destDevicesInTopoEditor, 1, 6);
+
+        Label device3 = new Label("Interface");
+        propertyGrid.add(device3, 0, 7);
+        interfaceList4 = new ComboBox<String>();
+        interfaceList4.setMinWidth(170);
+        propertyGrid.add(interfaceList4, 1, 7);
+
+        HBox propertyButton = new HBox(5);
+        propertyButton.setPadding(new Insets(0, 0, 0, 0));
+        finishSelectedLink = new Button("Save");
+
+        cancelButton = new Button("Cancel");
+        propertyButton.getChildren().addAll(new Label("       "), finishSelectedLink, cancelButton);
+        propertyGrid.add(propertyButton, 1, 8);
+
+        cancelButton.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent arg0) {
+                primaryStage.close();
+            }
+        });
+        StackPane root = new StackPane();
+        root.getChildren().add(propertyGrid);
+        primaryStage.setScene(new Scene(root, 450, 320));
+        primaryStage.show();
+    }
+}
diff --git a/TestON/TAI/src/tai_ofa/OFAWizard.java b/TestON/TAI/src/tai_ofa/OFAWizard.java
new file mode 100644
index 0000000..d046989
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/OFAWizard.java
@@ -0,0 +1,2204 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package tai_ofa;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.security.acl.Owner;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Observable;
+import java.util.Set;
+import java.util.Stack;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javafx.application.Application;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.geometry.Insets;
+import javafx.geometry.Orientation;
+import javafx.geometry.Side;
+import javafx.scene.Cursor;
+import javafx.scene.Node;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.Button;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.ComboBoxBuilder;
+import javafx.scene.control.ContextMenu;
+import javafx.scene.control.Label;
+import javafx.scene.control.MenuItem;
+import javafx.scene.control.MultipleSelectionModel;
+import javafx.scene.control.Separator;
+import javafx.scene.control.SingleSelectionModel;
+import javafx.scene.control.Tab;
+import javafx.scene.control.TabPane;
+import javafx.scene.control.TextField;
+import javafx.scene.control.TextFieldBuilder;
+import javafx.scene.control.ToolBar;
+import javafx.scene.control.Tooltip;
+import javafx.scene.control.TreeItem;
+import javafx.scene.control.TreeView;
+import javafx.scene.effect.DropShadow;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.ClipboardContent;
+import javafx.scene.input.DragEvent;
+import javafx.scene.input.Dragboard;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.input.MouseButton;
+import javafx.scene.input.MouseDragEvent;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.input.TransferMode;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.BorderPaneBuilder;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.GridPaneBuilder;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Pane;
+import javafx.scene.layout.Priority;
+import javafx.scene.layout.Region;
+import javafx.scene.layout.StackPane;
+import javafx.scene.layout.VBox;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Circle;
+import javafx.scene.shape.Line;
+import javafx.scene.shape.StrokeLineCap;
+import javafx.scene.text.Font;
+import javafx.scene.text.FontWeight;
+import javafx.scene.text.Text;
+import javafx.stage.Stage;
+
+/**
+ *
+ * @author Raghav Kashyap (raghavkashyap@paxterrasolutions.com)
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+ */
+public class OFAWizard extends Application {
+
+    NewWizard wizard;
+    TAI_OFA referenceOFA;
+
+    public OFAWizard() {
+    }
+    TreeItem<String> rootItem;
+    TreeItem<String> testTree;
+    ObservableList<TreeItem<String>> listProject;
+    TreeView<String> projectTree;
+    int caseNumber;
+    String paramsFileName;
+
+    public OFAWizard(TreeItem<String> root, int i, ObservableList<TreeItem<String>> listProject1, TreeView<String> projectTree1) {
+        rootItem = root;
+        caseNumber = i;
+        listProject = listProject1;
+        projectTree = projectTree1;
+    }
+
+    public void setOFA(TAI_OFA ofa) {
+        this.referenceOFA = ofa;
+    }
+
+    @Override
+    public void start(Stage stage) throws Exception {
+        wizard = new NewWizard(stage, rootItem, referenceOFA, caseNumber, listProject, projectTree);
+        stage.setTitle("TestON - Automation is O{pe}N ");
+        Scene scene = new Scene(wizard, 700, 400);
+        stage.setScene(scene);
+        stage.setResizable(false);
+        scene.getStylesheets().addAll(this.getClass().getResource("wizard.css").toExternalForm());
+        paramsFileName = wizard.paramsFileName;
+        stage.show();
+    }
+
+    public void setProjectList(ObservableList<TreeItem<String>> list) {
+        listProject = list;
+    }
+
+    public void setProjectView(TreeView<String> tree) {
+        projectTree = tree;
+    }
+}
+
+/**
+ * basic wizard infrastructure class
+ */
+class Wizard extends StackPane {
+
+    private static final int UNDEFINED = -1;
+    private ObservableList<WizardPage> pages = FXCollections.observableArrayList();
+    private Stack<Integer> history = new Stack();
+    private int curPageIdx = UNDEFINED;
+    NewWizard newWizardObjct;
+
+    public Wizard() {
+    }
+
+    void setAllData(WizardPage... nodes) {
+        for (WizardPage wizardPage : nodes) {
+            wizardPage.setNewWizard(newWizardObjct);
+            pages.add(wizardPage);
+        }
+        navTo(0);
+        setStyle("-fx-padding: 0; -fx-background-color: cornsilk;");
+    }
+
+    Wizard(WizardPage... nodes) {
+        for (WizardPage wizardPage : nodes) {
+            wizardPage.setNewWizard(newWizardObjct);
+            pages.add(wizardPage);
+        }
+        navTo(0);
+        setStyle("-fx-padding: 0; -fx-background-color: cornsilk;");
+    }
+
+    ObservableList<WizardPage> getAllChildrens() {
+        return pages;
+    }
+
+    void nextPage() {
+        if (hasNextPage()) {
+            navTo(curPageIdx + 1);
+        }
+    }
+
+    void priorPage() {
+        if (hasPriorPage()) {
+            navTo(history.pop(), false);
+        }
+    }
+
+    boolean hasNextPage() {
+        return (curPageIdx < pages.size() - 1);
+    }
+
+    boolean hasPriorPage() {
+        return !history.isEmpty();
+    }
+
+    void navTo(int nextPageIdx, boolean pushHistory) {
+        if (nextPageIdx < 0 || nextPageIdx >= pages.size()) {
+            return;
+        }
+        if (curPageIdx != UNDEFINED) {
+            if (pushHistory) {
+                history.push(curPageIdx);
+            }
+        }
+
+        WizardPage nextPage = pages.get(nextPageIdx);
+        curPageIdx = nextPageIdx;
+        getChildren().clear();
+        getChildren().add(nextPage);
+        nextPage.manageButtons();
+    }
+
+    void navTo(int nextPageIdx) {
+        navTo(nextPageIdx, true);
+    }
+
+    void navTo(String id) {
+        Node page = lookup("#" + id);
+        if (page != null) {
+            int nextPageIdx = pages.indexOf(page);
+            if (nextPageIdx != UNDEFINED) {
+                navTo(nextPageIdx);
+            }
+        }
+    }
+
+    public void finish() {
+    }
+
+    public void cancel() {
+    }
+
+    public void setNewWizard(NewWizard newWizardObj) {
+        newWizardObjct = newWizardObj;
+    }
+}
+
+/**
+ * basic wizard page class
+ */
+abstract class WizardPage extends VBox {
+
+    TAILocale label = new TAILocale(new Locale("en", "EN"));
+    Button priorButton = new Button("<< Previous");
+    Button nextButton = new Button("Next >>");
+    Button cancelButton = new Button("Cancel");
+    Button finishButton = new Button("Finish");
+    NewWizard newWizardReference;
+
+    WizardPage(String title) {
+        //getChildren().add(der.create().text(title).build());
+        setId(title);
+        setSpacing(0);
+        setStyle("-fx-padding:0; -fx-background-color: white; ");
+        Region spring = new Region();
+        VBox.setVgrow(spring, Priority.ALWAYS);
+        getChildren().addAll(getContent(), spring, getButtons());
+
+        priorButton.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent actionEvent) {
+                priorPage();
+            }
+        });
+
+        nextButton.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                nextPage();
+            }
+        });
+
+        cancelButton.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                getWizard().cancel();
+            }
+        });
+
+        finishButton.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                getWizard().finish();
+            }
+        });
+    }
+
+    HBox getButtons() {
+        Region spring = new Region();
+        HBox.setHgrow(spring, Priority.ALWAYS);
+        HBox buttonBar = new HBox(5);
+        cancelButton.setCancelButton(true);
+        //   finishButton.setDefaultButton(true);
+        buttonBar.getChildren().addAll(spring, priorButton, nextButton, cancelButton, finishButton);
+        return buttonBar;
+    }
+
+    abstract Parent getContent();
+
+    boolean hasNextPage() {
+        return getWizard().hasNextPage();
+    }
+
+    boolean hasPriorPage() {
+        return getWizard().hasPriorPage();
+    }
+
+    void nextPage() {
+        getWizard().nextPage();
+    }
+
+    void priorPage() {
+        getWizard().priorPage();
+    }
+
+    void navTo(String id) {
+        getWizard().navTo(id);
+    }
+
+    Wizard getWizard() {
+        return (Wizard) getParent();
+    }
+
+    public void manageButtons() {
+        if (!hasPriorPage()) {
+            priorButton.setDisable(true);
+        }
+
+        if (!hasNextPage()) {
+            nextButton.setDisable(true);
+        }
+    }
+
+    public void setNewWizard(NewWizard refWizard) {
+        newWizardReference = refWizard;
+    }
+}
+
+/*
+ * this Class shows the OFA wizard
+ */
+class NewWizard extends Wizard {
+
+    String[] splitDeviceDetails;
+    TestWizard testWizard;
+    Stage owner;
+    String topologyDemo, paramFileDemo, ospkFileDemo;
+    TreeItem<String> projectExplorerTreeItem;
+    OFALoadTree projectNameTree;
+    TAI_OFA referenceOFA;
+    TAILocale label = new TAILocale(new Locale("en", "EN"));
+    String OFAUiPath = label.hierarchyTestON + "/tests/";
+    TreeItem<String> treeItem1;
+    String paramsFileName, topoFileName;
+    boolean flag = false;
+    String topologyFileDemo;
+    String[] splitDeviceDetail;
+
+    public NewWizard(Stage owner, TreeItem<String> treeItem, TAI_OFA reference, int caseNumber, final ObservableList<TreeItem<String>> listProject1, TreeView<String> projectTree1) {
+        super();
+
+        super.setNewWizard(this);
+
+        this.owner = owner;
+        testWizard = new TestWizard();
+
+        switch (caseNumber) {
+            /*
+             * cases --- 
+             *     1. New Project
+             *     2. New Params file
+             *     3. New Topology file
+             *     4. New Driver 
+             *     
+             */
+            case 1:
+                final ProjectWizard projectWizard = new ProjectWizard();
+                ParamsWizard paramsWizard = new ParamsWizard();
+                super.setAllData(projectWizard, paramsWizard, new TopologyWizard());
+                projectWizard.projectName.textProperty().addListener(new ChangeListener<String>() {
+                    @Override
+                    public void changed(ObservableValue<? extends String> arg0, String arg1, String arg2) {
+                        String message = "\nYour projectName must be\n" + "started with alphabate and \nshould not have special symbol";
+                        textValidation("([a-zA-Z]\\d*[a-zA_Z])+|([a-zA-Z]\\d*)+|", arg2, projectWizard.error, projectWizard.nextButton, message, projectWizard.projectName);
+                    }
+                });
+                projectExplorerTreeItem = treeItem;
+                referenceOFA = reference;
+                paramsWizard.gridPane.add(testWizard.testParams, 0, 0);
+                paramsWizard.gridPane.add(new Label(label.wizEmailId), 0, 2);
+                paramsWizard.gridPane.add(testWizard.emailId, 1, 2);
+                paramsWizard.gridPane.add(new Label("Log Directory "), 0, 3);
+                paramsWizard.gridPane.add(testWizard.log_dir, 1, 3);
+                paramsWizard.gridPane.add(new Label(label.wizNumberofTestCases), 0, 4);
+                paramsWizard.gridPane.add(testWizard.testCases, 1, 4);
+                paramsWizard.gridPane.add(testWizard.imageHouse, 60, 0);
+                paramsWizard.nextButton.setDisable(false);
+                break;
+
+            case 2:
+
+                super.setAllData(testWizard);
+                projectExplorerTreeItem = treeItem;
+                referenceOFA = reference;
+                testWizard.gridPane.add(new Label(label.wizProject), 0, 1);
+                testWizard.gridPane.add(testWizard.projectNameList, 1, 1);
+                testWizard.gridPane.add(new Label(label.wizParamName), 0, 3);
+
+                testWizard.gridPane.add(testWizard.paramName, 1, 3);
+
+                testWizard.nextButton.setDisable(true);
+
+                testWizard.paramName.textProperty().addListener(new ChangeListener<String>() {
+                    @Override
+                    public void changed(ObservableValue<? extends String> arg0, String arg1, String arg2) {
+                        if (!arg2.isEmpty()) {
+                            testWizard.projectNameList.valueProperty().addListener(new ChangeListener() {
+                                @Override
+                                public void changed(ObservableValue arg0, Object arg1, Object arg2) {
+                                    if (!arg2.toString().isEmpty()) {
+                                        testWizard.testNameList.valueProperty().addListener(new ChangeListener() {
+                                            @Override
+                                            public void changed(ObservableValue arg0, Object arg1, Object arg2) {
+                                                testWizard.finishButton.setDisable(arg2.toString().isEmpty());
+                                            }
+                                        });
+                                    }
+                                }
+                            });
+                        }
+                    }
+                });
+                Iterator<TreeItem<String>> projectList1 = listProject1.iterator();
+                testWizard.projectNameList.getItems().clear();
+                while (projectList1.hasNext()) {
+                    TreeItem<String> projectComb = projectList1.next();
+                    projectComb.getValue();
+                    testWizard.projectNameList.getItems().add(projectComb.getValue());
+                }
+
+                testWizard.projectNameList.setOnAction(new EventHandler<ActionEvent>() {
+                    @Override
+                    public void handle(ActionEvent arg0) {
+
+                        final Iterator<TreeItem<String>> projectIterator = listProject1.iterator();
+                        while (projectIterator.hasNext()) {
+                            final TreeItem<String> treeItem = projectIterator.next();
+                            ObservableList<TreeItem<String>> list = treeItem.getChildren();
+                            if (treeItem.getValue().equalsIgnoreCase(testWizard.projectNameList.getSelectionModel().getSelectedItem().toString())) {
+                                ObservableList<TreeItem<String>> children = treeItem.getChildren();
+                                final Iterator<TreeItem<String>> testListIterator = children.iterator();
+                                while (testListIterator.hasNext()) {
+                                    TreeItem<String> testComb = testListIterator.next();
+                                    testComb.getValue();
+                                }
+                            }
+                        }
+                    }
+                });
+                break;
+
+            case 3:
+                final ParamsWizard paramWizard = new ParamsWizard();
+                super.setAllData(paramWizard, new TopologyWizard());
+                projectExplorerTreeItem = treeItem;
+                referenceOFA = reference;
+                paramWizard.gridPane.add(testWizard.testParams, 0, 0);
+                paramWizard.gridPane.add(new Label("Test Name :"), 0, 2);
+                paramWizard.gridPane.add(testWizard.projectNameList, 1, 2);
+                paramWizard.gridPane.add(new Label("Topology Name"), 0, 3);
+                paramWizard.gridPane.add(testWizard.topologyName, 1, 3);
+                paramWizard.gridPane.add(testWizard.imageHouse, 60, 0);
+                paramWizard.nextButton.setDisable(true);
+                Iterator<TreeItem<String>> projectList2 = listProject1.iterator();
+                testWizard.projectNameList.getItems().clear();
+                while (projectList2.hasNext()) {
+                    TreeItem<String> projectComb = projectList2.next();
+                    projectComb.getValue();
+                    testWizard.projectNameList.getItems().add(projectComb.getValue());
+                }
+
+                testWizard.projectNameList.setOnAction(new EventHandler<ActionEvent>() {
+                    @Override
+                    public void handle(ActionEvent arg0) {
+
+                        final Iterator<TreeItem<String>> projectIterator = listProject1.iterator();
+                        while (projectIterator.hasNext()) {
+                            final TreeItem<String> treeItem = projectIterator.next();
+                            ObservableList<TreeItem<String>> list = treeItem.getChildren();
+                            if (treeItem.getValue().equalsIgnoreCase(testWizard.projectNameList.getSelectionModel().getSelectedItem().toString())) {
+                                ObservableList<TreeItem<String>> children = treeItem.getChildren();
+                                final Iterator<TreeItem<String>> testListIterator = children.iterator();
+                                while (testListIterator.hasNext()) {
+                                    TreeItem<String> testComb = testListIterator.next();
+                                    testComb.getValue();
+                                }
+                            }
+                        }
+                    }
+                });
+
+                testWizard.topologyName.setOnKeyReleased(new EventHandler<KeyEvent>() {
+                    @Override
+                    public void handle(KeyEvent t) {
+                        if (!testWizard.topologyName.getText().isEmpty()) {
+                            paramWizard.nextButton.setDisable(false);
+                        } else {
+                            paramWizard.nextButton.setDisable(true);
+                        }
+                    }
+                });
+                break;
+        }
+    }
+
+    @Override
+    public void finish() {
+        String projectName = null;
+        String testName = null;
+        String testParamsName = null;
+        String testTopologyName = null;
+        ObservableList<WizardPage> nodeList = super.getAllChildrens();
+        int i = 0;
+
+        while (i < nodeList.size()) {
+            WizardPage node = nodeList.get(i);
+            if (node.getId().equals(label.wizProjectWizardId)) {
+                ProjectWizard projectWizard = (ProjectWizard) node;
+                projectName = projectWizard.getName();
+                new File(OFAUiPath + projectName).mkdir();
+                String projectWorkSpacePath = OFAUiPath + projectName;
+                File[] file = File.listRoots();
+                Path name = new File(projectWorkSpacePath).toPath();
+                projectNameTree = new OFALoadTree(name);
+
+                projectExplorerTreeItem.getChildren().add(projectNameTree);
+                String pathToFiles = projectNameTree.getFullPath() + "/";
+
+
+                Path ospkName = new File(projectNameTree.getFullPath() + "/" + projectName + ".ospk").toPath();
+                Path paramsName = new File(projectNameTree.getFullPath() + "/" + projectName + ".params").toPath();
+                Path topologyName = new File(projectNameTree.getFullPath() + "/" + projectName + ".topo").toPath();
+
+                OFALoadTree topologyTestTree = new OFALoadTree(topologyName);
+                topologyTestTree.setValue(topologyName.toString().replace(topologyName.toString(), projectName));
+
+                OFALoadTree ospkTestTree = new OFALoadTree(ospkName);
+                ospkTestTree.setValue(ospkName.toString().replace(ospkName.toString(), projectName));
+
+                OFALoadTree paramTestTree = new OFALoadTree(paramsName);
+                paramTestTree.setValue(paramsName.toString().replace(paramsName.toString(), projectName));
+                projectNameTree.getChildren().addAll(topologyTestTree, paramTestTree, ospkTestTree);
+
+                paramFileDemo = "<PARAMS>" + "\n\t" + "<testcases>  \"1\" </testcases>" + "\n\t"
+                        + "<mail> " + testWizard.emailId.getText() + "</mail>\n\t" + "<log_dir>" + testWizard.log_dir.getText() + "</log_dir>" + "\n\n\t"
+                        + "<CASE1>" + "\n\t\t" + "#Enter your CASE parameter here in the form" + "\n\t\t" + "#param = value"
+                        + "\n\t\t" + "<STEP1>" + "\n\t\t\t" + "#Enter your STEP parameter here in the form" + "\n\t\t\t" + "#param = value" + "\n\t\t" + "</STEP1>" + "\n\t" + "</CASE1>"
+                        + "\n" + "\n</PARAMS>";
+
+                ospkFileDemo = "CASE 1" + "\n" + "\t" + "NAME" + " " + "\"Give test case name \"" + "\n" + "\t"
+                        + "DESC \"Give test case description\"" + "\n" + "END CASE";
+
+                testTopologyName = projectName + ".topo";
+                String topoFileDemo = "<TOPOLOGY>" + "\n\t<COMPONENT>" + "\n\t\t# put components here as given below" + "\n\t\t<component1>" + "\n\t\t\t# put component parameters here"
+                        + "\n\t\t  <host> 192.168.56.101 </host>" + "\n\t\t</component1>" + "\n\t</COMPONENT>" + "</TOPOLOGY>";
+
+                try {
+                    new File(pathToFiles + "/" + projectName + ".ospk").createNewFile();
+                    new File(pathToFiles + "/" + projectName + ".params").createNewFile();
+                    new File(pathToFiles + "/" + projectName + ".topo").createNewFile();
+                    new File(pathToFiles + "/" + "__init__.py").createNewFile();
+                } catch (IOException ex) {
+                   
+                }
+                writeInFile(pathToFiles + "/" + projectName + ".params", paramFileDemo);
+                writeInFile(pathToFiles + "/" + projectName + ".ospk", ospkFileDemo);
+                
+                referenceOFA.checkEditor();
+                
+            } else if (node.getId().equals(label.wizTestWizardId)) {
+
+                testWizard = (TestWizard) node;
+                String selectedProject = testWizard.projectNameList.getSelectionModel().getSelectedItem().toString();
+                String paramName = testWizard.paramName.getText();
+                String pathParams = "";
+                for (int index = 0; index < referenceOFA.projectExplorerTree.getChildren().size(); index++) {
+
+                    if (referenceOFA.projectExplorerTree.getChildren().get(index).getValue().equals(selectedProject)) {
+
+                        pathParams = OFAUiPath + selectedProject;
+                        Path name = new File(OFAUiPath + selectedProject + "/" + paramName).toPath();
+                        OFALoadTree testSelection = new OFALoadTree(name);
+
+                        Path paramsName = new File(name + ".params").toPath();
+                        paramsFileName = paramsName.toString();
+                        OFALoadTree paramsTestTree = new OFALoadTree(paramsName);
+                        paramsTestTree.setValue(paramName);
+                        referenceOFA.projectExplorerTree.getChildren().get(index).getChildren().addAll(paramsTestTree);
+                        try {
+                            new File(paramsFileName).createNewFile();
+                        } catch (IOException ex) {
+                            Logger.getLogger(NewWizard.class.getName()).log(Level.SEVERE, null, ex);
+                        }
+                        writeInFile(paramsFileName, referenceOFA.paramsFileContent);
+                    }
+                }
+
+
+            } else if (node.getId().equals(label.wizTopologyWizardId)) {
+                TopologyWizard topoWizard = (TopologyWizard) node;
+
+                ArrayList<String> deviceName = new ArrayList<String>();
+                Iterator<TextField> attributeIterator = topoWizard.getDeviceNameList().iterator();
+                while (attributeIterator.hasNext()) {
+                    TextField iteratorAttributeText = attributeIterator.next();
+                    deviceName.add(iteratorAttributeText.getText());
+                }
+                topologyFileDemo = "<TOPOLOGY>" + "\n\t" + "<COMPONENT>" + "\n\t";
+
+                for (String device : topoWizard.getPropertyDetail()) {
+                    splitDeviceDetail = device.split("\n");
+                    topologyFileDemo += "\n\t\t" + "<" + splitDeviceDetail[0] + ">";
+                    splitDeviceDetail = device.split("\n");
+                    try {
+                        topologyFileDemo += "\n\t\t\t" + "<hostname> " + splitDeviceDetail[1] + "</hostname>\n\t\t\t" + "<user>" + splitDeviceDetail[2]
+                                + "</user>\n\t\t\t" + "<password>" + splitDeviceDetail[3] + "</password>\n\t\t\t" + "<type>" + splitDeviceDetail[5] + "</type>\n\t\t\t" + "<coordinate(x,y)>"
+                                + splitDeviceDetail[7] + "</coordinate(x,y)>\n\t\t\t";
+
+                        if (topoWizard.topoplogy.testTargetRadioButton.isSelected()) {
+                            topologyFileDemo += "<test_target> 1 </test_target>\n\t\t\t" + "<COMPONENTS>";
+                        } else {
+                            topologyFileDemo += "<COMPONENTS>";
+                        }
+                        String[] deviceDetailsArray = topoWizard.interFaceValue.toArray(new String[topoWizard.interFaceValue.size()]);
+                        int noOfDevices = 0;
+                        for (String name : topoWizard.interFaceName) {
+                            String propertyDetail = deviceDetailsArray[noOfDevices++];
+                            String[] details = propertyDetail.split("\\_");
+                            String[] splitInterFace = name.split("\\_");
+                            if (splitInterFace[1].equals(splitDeviceDetail[0]) && details[1].equals(splitDeviceDetail[0])) {
+                                //              topologyFileDemo +=  "\n\t\t\t"+splitInterFace[0]+"="+details[0];
+                            }
+                        }
+                        for (HashMap<String, String> interFaceDetail : topoWizard.arrayOfInterFaceHash) {
+                            Set set = interFaceDetail.entrySet();
+                            Iterator interFaceHashDetailIterator = set.iterator();
+                            while (interFaceHashDetailIterator.hasNext()) {
+                                Map.Entry me = (Map.Entry) interFaceHashDetailIterator.next();
+                                String[] deviceNameAndiniterFaceValue = me.getValue().toString().split("\\_");
+                                if (deviceNameAndiniterFaceValue[1].equals(splitDeviceDetail[0])) {
+                                    if (!me.getKey().toString().isEmpty()) {
+                                        if (!me.getKey().toString().equals("//s+")) {
+                                            topologyFileDemo += "\n\t\t\t\t" + "<" + me.getKey().toString() + ">" + deviceNameAndiniterFaceValue[0].toString() + "</" + me.getKey().toString() + ">";
+
+                                        }
+                                    }
+                                }
+
+                            }
+                            topologyFileDemo += "\n\t\t\t</COMPONENTS>";
+                        }
+
+                        topologyFileDemo += "\n\t\t" + "</" + splitDeviceDetail[0] + ">";
+
+                    } catch (Exception e) {
+                    }
+                }
+                Set set = topoWizard.linkTopologyHash.entrySet();
+                Iterator linkHashDetailIterator = set.iterator();
+                while (linkHashDetailIterator.hasNext()) {
+                    Map.Entry me = (Map.Entry) linkHashDetailIterator.next();
+
+                    String[] linkValue = me.getValue().toString().split("_");
+                    String[] linkCoordinates = me.getKey().toString().split("_");
+
+                    topologyFileDemo += "\n\t\t" + "<" + linkValue[0] + ">";
+                    topologyFileDemo += "\n\t\t\t" + "<" + linkValue[2].toString() + ">" + linkValue[3].toString() + "</" + linkValue[2].toString() + ">";
+                    topologyFileDemo += "\n\t\t\t" + "<" + linkValue[4].toString() + ">" + linkValue[5].toString() + "</" + linkValue[4].toString() + ">";
+                    topologyFileDemo += "\n\t\t\t" + "<linkCoordinates(startx,starty,endx,endy)" + ">" + linkCoordinates[1].toString() + "," + linkCoordinates[2] + "," + linkCoordinates[3] + "," + linkCoordinates[4] + "</linkCoordinates(startx,starty,endx,endy)" + ">";
+                    topologyFileDemo += "\n\t\t" + "</" + linkValue[0] + ">";
+
+                }
+
+                topologyFileDemo += "\n\t" + "</COMPONENT>" + "\n" + "</TOPOLOGY>";
+                String pathTopo = "";
+                if (testTopologyName != null) {
+                    writeInFile(label.hierarchyTestON + "/tests/" + projectName + "/" + testTopologyName, topologyFileDemo);
+                } else {
+                    String projectNames = testWizard.projectNameList.getSelectionModel().getSelectedItem().toString();
+                    for (int index = 0; index < referenceOFA.projectExplorerTree.getChildren().size(); index++) {
+
+                        if (referenceOFA.projectExplorerTree.getChildren().get(index).getValue().equals(projectNames)) {
+                            pathTopo = OFAUiPath + projectNames;
+                            Path name = new File(OFAUiPath + projectNames + "/" + testWizard.topologyName.getText()).toPath();
+                            OFALoadTree testSelection = new OFALoadTree(name);
+
+                            Path topoName = new File(name + ".topo").toPath();
+                            topoFileName = topoName.toString();
+                            OFALoadTree topoTestTree = new OFALoadTree(topoName);
+                            topoTestTree.setValue(topoFileName);
+                            topoTestTree.setValue(topoFileName.toString().replace(topoFileName.toString(), testWizard.topologyName.getText()));
+
+                            referenceOFA.projectExplorerTree.getChildren().get(index).getChildren().addAll(topoTestTree);
+                            try {
+                                new File(topoFileName).createNewFile();
+                            } catch (IOException ex) {
+                                Logger.getLogger(NewWizard.class.getName()).log(Level.SEVERE, null, ex);
+                            }
+                            writeInFile(topoFileName, topologyFileDemo);
+                        }
+                    }
+
+                }
+
+            }
+
+            i++;
+        }
+        owner.close();
+    }
+
+    public String getParamsFileName() {
+        return paramsFileName;
+    }
+
+    public void writeInFile(String path, String demoFile) {
+        try {
+            // Create file 
+            FileWriter fstream = new FileWriter(path);
+            BufferedWriter out = new BufferedWriter(fstream);
+            out.write(demoFile);
+            out.close();
+        } catch (Exception e) {
+            
+        }
+    }
+
+    public void cancel() {
+
+        owner.close();
+    }
+
+    public void textValidation(String regExp, String arg2, Label error, Button nextButton, String text, TextField name) {
+        Tooltip tooltip = new Tooltip();
+        if (arg2.matches(regExp)) {
+            error.setVisible(false);
+            nextButton.setDisable(false);
+        } else {
+            error.setVisible(true);
+            nextButton.setDisable(true);
+            flag = true;
+            String errorImage = "/images/error.png";
+            Image saveImage = new Image(getClass().getResourceAsStream(errorImage), 18.0, 18.0, true, true);
+            ImageView imageSave = new ImageView(saveImage);
+            error.setGraphic(imageSave);
+
+            tooltip.autoFixProperty();
+            tooltip.setText(text);
+            tooltip.setStyle("-fx-background-color:white");
+            error.setTooltip(tooltip);
+            Image image = new Image(getClass().getResourceAsStream("/images/error.png"), 24.0, 24.0, true, true);
+            tooltip.setGraphic(new ImageView(image));
+        }
+        if (arg2.isEmpty() || flag == true) {
+            nextButton.setDisable(true);
+            flag = false;
+        }
+    }
+}
+
+/**
+ * This page gathers more information about the new Test
+ */
+class ProjectWizard extends WizardPage {
+
+    TextField projectName;
+    String newProjectName;
+    String name;
+    boolean flag = false;
+    Label error;
+    ImageView imageHouse;
+
+    public ProjectWizard() {
+        super("Project");
+
+        nextButton.setDisable(true);
+
+        finishButton.setDisable(true);
+        this.setId("projectWizard");
+
+    }
+
+    @Override
+    Parent getContent() {
+        projectName = TextFieldBuilder.create().build();
+
+        projectName.setMinWidth(170);
+        nextButton.setDisable(true);
+        error = new Label();
+        error.setVisible(false);
+
+        error.setTextFill(Color.RED);
+        imageHouse = new ImageView(new Image("images/paxterra_logo.jpg", 100, 100, true, true));
+
+        HBox image = new HBox();
+        image.setPadding(new Insets(0, 0, 0, 470));
+        Button Open = new Button();
+        String openImgPath = "/images/TestON.png";
+        Open.setStyle("-fx-background-color:white");
+        Open.setLayoutX(0);
+        Open.setLayoutY(0);
+        GridPane gridPane = new GridPane();
+        gridPane.setPadding(new Insets(70, 0, 0, 200));
+        gridPane.setHgap(10);
+        gridPane.setVgap(8);
+        Label project = new Label("Project Name");
+
+
+        gridPane.setId("pane");
+        gridPane.add(project, 0, 11);
+        gridPane.add(projectName, 1, 11);
+        gridPane.add(error, 2, 10);
+        gridPane.add(imageHouse, 10, 0);
+
+        return GridPaneBuilder.create().children(gridPane).build();
+
+    }
+
+    void nextPage() {
+        // If they have complaints, go to the normal next page
+
+        if (!projectName.getText().equals("")) {
+            super.nextPage();
+            newProjectName = projectName.getText();
+
+        } else {
+
+            // No complaints? Short-circuit the rest of the pages
+            navTo("ParamsWizard");
+        }
+    }
+
+    public String getName() {
+        return newProjectName;
+    }
+}
+
+/**
+ * This page gathers more information about the Test Script
+ */
+class TestWizard extends WizardPage {
+
+    TextField emailIds;
+    TextField numberOfTestCase;
+    TextField paramName;
+    TextField topologyName;
+    String getTestName, getEmailId;
+    String getNumberOfTestCases;
+    ObservableList<TreeItem<String>> listProject;
+    TreeView<String> projectTree;
+    ComboBox projectNameList;
+    ComboBox testNameList;
+    GridPane gridPane;
+    Label projectError, testError, emailIdError;
+    ImageView imageHouse;
+    Text testParams;
+    TextField testCases;
+    TextField emailId;
+    TextField log_dir;
+    Text caseParameter;
+    Button addParams;
+
+    public TestWizard() {
+        super("More Info");
+        this.setId("testWizard");
+        nextButton.setDisable(true);
+        finishButton.setDisable(false);
+    }
+
+    @Override
+    Parent getContent() {
+
+        HBox image = new HBox();
+        image.setPadding(new Insets(0, 0, 0, 470));
+
+        topologyName = TextFieldBuilder.create().build();
+        testParams = new Text("Test Params :");
+        testParams.setFont(Font.font("Arial", FontWeight.BOLD, 15));
+        testParams.setFill(Color.BLUE);
+        testCases = TextFieldBuilder.create().build();
+        emailId = TextFieldBuilder.create().build();
+        log_dir = TextFieldBuilder.create().build();
+        caseParameter = new Text("Case Params");
+        caseParameter.setFont(Font.font("Arial", FontWeight.BOLD, 10));
+        addParams = new Button("Add Case Params");
+        projectNameList = ComboBoxBuilder.create().build();
+        projectError = new Label();
+        projectError.setDisable(true);
+        paramName = TextFieldBuilder.create().build();
+        imageHouse = new ImageView(new Image("images/TestON.png", 200, 200, true, true));
+
+        testCases.lengthProperty().addListener(new ChangeListener<Number>() {
+            @Override
+            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
+                if (newValue.intValue() > oldValue.intValue()) {
+                    char ch = testCases.getText().charAt(oldValue.intValue());
+                    //Check if the new character is the number or other's
+                    if (!(ch >= '0' && ch <= '9')) {
+                        testCases.setText(testCases.getText().substring(0, testCases.getText().length() - 1));
+                    }
+                }
+            }
+        });
+
+        nextButton.setDisable(false);
+        finishButton.setDisable(false);
+        gridPane = new GridPane();
+        gridPane.setPadding(new Insets(30, 0, 0, 40));
+        gridPane.setHgap(0);
+        gridPane.setVgap(5);
+        return GridPaneBuilder.create().children(gridPane).build();
+    }
+
+    void nextPage() {
+
+        if (!emailId.getText().equals("") || numberOfTestCase.getText().equals("") || log_dir.getText().equals("")) {
+            super.nextPage();
+
+            getEmailId = emailId.getText();
+            getNumberOfTestCases = numberOfTestCase.getText();
+        } else {
+
+            navTo("topologyWizards");
+        }
+    }
+
+    public String getTestName() {
+        return getTestName;
+    }
+
+    public String getEmailId() {
+        return getEmailId;
+    }
+
+    public String getNumberOfTestCase() {
+        return getNumberOfTestCases;
+    }
+}
+
+/**
+ * This page gathers more information about the new Params File
+ */
+class ParamsWizard extends WizardPage {
+
+    TextField emailIds;
+    TextField numberOfTestCase;
+    TextField paramName;
+    TextField topologyName;
+    String getTestName, getEmailId;
+    String getNumberOfTestCases;
+    ObservableList<TreeItem<String>> listProject;
+    TreeView<String> projectTree;
+    ComboBox projectNameList;
+    ComboBox testNameList;
+    GridPane gridPane;
+    Label projectError, testError, emailIdError;
+    ImageView imageHouse;
+    // here is new list
+    Text testParams;
+    TextField testCases;
+    TextField emailId;
+    TextField log_dir;
+    Text caseParameter;
+    Button addParams;
+    TextField testTopology;
+
+    public ParamsWizard() {
+        super("More Info");
+        this.setId("paramsWizard");
+        nextButton.setDisable(true);
+        finishButton.setDisable(false);
+    }
+
+    @Override
+    Parent getContent() {
+
+        HBox image = new HBox();
+        image.setPadding(new Insets(0, 0, 0, 470));
+
+        testTopology = emailId = TextFieldBuilder.create().build();
+        testParams = new Text("Test Params :");
+        testParams.setId("testParamsTitle");
+        testParams.setFont(Font.font("Arial", FontWeight.BOLD, 15));
+        testParams.setFill(Color.BLUE);
+
+        DropShadow dropShadow = new DropShadow();
+        dropShadow.setColor(Color.BLACK);
+        dropShadow.setRadius(25);
+        dropShadow.setSpread(0.25);
+        testParams.setEffect(dropShadow);
+
+        testCases = TextFieldBuilder.create().build();
+        emailId = TextFieldBuilder.create().build();
+        log_dir = TextFieldBuilder.create().build();
+        caseParameter = new Text("Case Params");
+        caseParameter.setFont(Font.font("Arial", FontWeight.BOLD, 10));
+        addParams = new Button("Add Case Params");
+        projectNameList = ComboBoxBuilder.create().build();
+        projectError = new Label();
+        projectError.setDisable(true);
+        paramName = TextFieldBuilder.create().build();
+        imageHouse = new ImageView(new Image("images/paxterra_logo.jpg", 100, 100, true, true));
+
+        testCases.lengthProperty().addListener(new ChangeListener<Number>() {
+            @Override
+            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
+                if (newValue.intValue() > oldValue.intValue()) {
+                    char ch = testCases.getText().charAt(oldValue.intValue());
+                    //Check if the new character is the number or other's
+                    if (!(ch >= '0' && ch <= '9')) {
+                        testCases.setText(testCases.getText().substring(0, testCases.getText().length() - 1));
+                    }
+                }
+            }
+        });
+        nextButton.setDisable(false);
+        finishButton.setDisable(false);
+
+        gridPane = new GridPane();
+        gridPane.setPadding(new Insets(30, 0, 0, 40));
+        gridPane.setHgap(0);
+        gridPane.setVgap(5);
+
+        return GridPaneBuilder.create().children(gridPane).build();
+
+    }
+
+    void nextPage() {
+
+        if (!emailId.getText().equals("") || testCases.getText().equals("") || log_dir.getText().equals("")) {
+            super.nextPage();
+
+            getEmailId = emailId.getText();
+            getNumberOfTestCases = testCases.getText();
+        } else {
+
+            navTo("topologyWizards");
+        }
+    }
+
+    public String getTestName() {
+        return getTestName;
+    }
+
+    public String getEmailId() {
+        return getEmailId;
+    }
+
+    public String getNumberOfTestCase() {
+        return getNumberOfTestCases;
+    }
+}
+
+/**
+ * This page gathers more information about the Test Topology
+ */
+class TopologyWizard extends WizardPage {
+
+    ArrayList<TextField> deviceNameList = new ArrayList<TextField>();
+    ArrayList<String> draggedImagesName = new ArrayList<String>();
+    OFATopology topoplogy;
+    ArrayList<String> propertyValue = new ArrayList<String>();
+    ArrayList<String> interFaceName = new ArrayList<String>();
+    ArrayList<String> interFaceValue = new ArrayList<String>();
+    TreeView<String> driverExplorerTreeView;
+    ArrayList<String> webInfoList = new ArrayList<String>();
+    ArrayList<String> webCisco = new ArrayList<String>();
+    HashMap<String, String> interFaceHashDetail = new HashMap<String, String>();
+    ArrayList<HashMap<String, String>> arrayOfInterFaceHash;
+    HashMap<String, String> webToplogyHash = new HashMap<String, String>();
+    ArrayList<HashMap<String, String>> arrayOfwebTopologyHash;
+    OFATopologyLink topologyLink = new OFATopologyLink();
+    HashMap<String, String> linkTopologyHash = new HashMap<String, String>();
+    ArrayList<HashMap<String, String>> arrayOfLinkTopologyHash = new ArrayList<HashMap<String, String>>();
+    ArrayList<String> topoEditorDeviceInfo = new ArrayList<String>();
+    Button lineButtonHorizontal;
+    TAILocale label = new TAILocale(new Locale("en", "EN"));
+    boolean anchorFlag = false;
+    boolean selectFlag = false;
+
+    public TopologyWizard() {
+        super("");
+        this.setId(label.wizTopologyWizardId);
+    }
+
+    Parent getContent() {
+        TAILocale label = new TAILocale(Locale.ENGLISH);
+        VBox parentTopologyBox = new VBox();
+        ToolBar canvasToolBar = new ToolBar();
+        lineButtonHorizontal = new Button();
+
+        Tooltip horizontal = new Tooltip("Click to add horizontal line in canvas");
+        lineButtonHorizontal.setTooltip(horizontal);
+        Image image = new Image(getClass().getResourceAsStream("/images/Link1.png"), 28.0, 28.0, true, true);
+        ImageView imageNew = new ImageView(image);
+        lineButtonHorizontal.setGraphic(imageNew);
+
+        Button lineButtonVertical = new Button();
+        Tooltip vertical = new Tooltip("Click to add vertical line in canvas");
+        lineButtonVertical.setTooltip(vertical);
+
+        final Button deleteAllButton = new Button();
+        Tooltip delete = new Tooltip("Click to reset or clear canvas");
+        deleteAllButton.setTooltip(delete);
+        Image image2 = new Image(getClass().getResourceAsStream("/images/Refresh.png"), 24.0, 24.0, true, true);
+        ImageView imageNew2 = new ImageView(image2);
+        deleteAllButton.setGraphic(imageNew2);
+
+        Image image1 = new Image(getClass().getResourceAsStream("/images/verticalLine.jpg"), 24.0, 24.0, true, true);
+        ImageView imageNew1 = new ImageView(image1);
+        lineButtonVertical.setGraphic(imageNew1);
+
+        canvasToolBar.getItems().addAll(lineButtonHorizontal, deleteAllButton);
+        HBox topologyBox = new HBox();
+        TabPane topologyPane = new TabPane();
+        topologyPane.setSide(Side.LEFT);
+        final Tab topologyModifiedDriverExplorerTab = new Tab("DEVICES");
+        topologyPane.setMaxWidth(250);
+
+        String hostName = label.hierarchyTestON + "/drivers/common";
+        final Node rootIcon = new ImageView(new Image(getClass().getResourceAsStream("/images/project.jpeg"), 16, 16, true, true));
+        TreeItem<String> driverExplorerTree = new TreeItem<String>("Drivers");
+        File[] file = File.listRoots();
+        Path name = new File(hostName).toPath();
+        LoadDirectory treeNode = new LoadDirectory(name);
+        driverExplorerTree = treeNode;
+        driverExplorerTree.setExpanded(true);
+        driverExplorerTreeView = new TreeView<String>(driverExplorerTree);
+        topologyModifiedDriverExplorerTab.setContent(driverExplorerTreeView);
+        driverExplorerTreeView.setShowRoot(false);
+        topologyPane.getTabs().add(topologyModifiedDriverExplorerTab);
+        topologyModifiedDriverExplorerTab.setClosable(false);
+
+        final TabPane topologyNewCanvas = new TabPane();
+        topologyNewCanvas.setSide(Side.BOTTOM);
+        final Tab canvasTab = new Tab("Canvas");
+        canvasTab.setClosable(false);
+        Button mew = new Button("CLICK");
+        mew.setGraphic(rootIcon);
+        HBox hBox1 = new HBox();
+        hBox1.setPrefWidth(345);
+        hBox1.setPrefHeight(200);
+        hBox1.setStyle("-fx-border-color: blue;"
+                + "-fx-border-width: 1;"
+                + "-fx-border-style: solid;");
+        Pane box1 = new Pane();
+        box1.setPrefWidth(500);
+        box1.setPrefHeight(200);
+        canvasTab.setContent(box1);
+        topologyNewCanvas.getTabs().add(canvasTab);
+        deleteAllButton.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent arg0) {
+                Pane pane = (Pane) canvasTab.getContent();
+                ObservableList<Node> list = pane.getChildren();
+                pane.getChildren().removeAll(list);
+
+            }
+        });
+        lineButtonVertical.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent arg0) {
+                final Line connecting = new Line();
+                connecting.setStrokeWidth(3);
+                connecting.setEndY(90);
+                connecting.setLayoutX(33);
+                connecting.setLayoutY(33);
+
+                final DraggableNode contentLine = new DraggableNode();
+                contentLine.setOnMouseClicked(new EventHandler<MouseEvent>() {
+                    @Override
+                    public void handle(MouseEvent arg0) {
+                        if (arg0.getClickCount() == 2) {
+                            OFATopologyLink topologyLink = new OFATopologyLink();
+                            topologyLink.start(new Stage());
+                        } else if (arg0.getButton() == MouseButton.SECONDARY) {
+                            deleteLineContextMenu(contentLine, connecting, arg0);
+                        }
+                    }
+                });
+
+                contentLine.getChildren().add(connecting);
+
+                Pane created = (Pane) canvasTab.getContent();
+
+                created.getChildren().addAll(contentLine);
+            }
+        });
+
+        driverExplorerTreeView.setOnDragDetected(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent arg0) {
+                final MultipleSelectionModel<TreeItem<String>> selectedItem = driverExplorerTreeView.getSelectionModel();
+                try {
+                    Image i = new Image(selectedItem.getSelectedItem().getGraphic().getId(), 60, 60, true, true);
+                    Dragboard db = driverExplorerTreeView.startDragAndDrop(TransferMode.COPY);
+
+                    ClipboardContent content = new ClipboardContent();
+                    content.putImage(i);
+                    db.setContent(content);
+
+                    arg0.consume();
+                } catch (Exception e) {
+                }
+
+            }
+        });
+
+        final Pane pane = (Pane) canvasTab.getContent();
+        pane.setOnDragOver(new EventHandler<DragEvent>() {
+            @Override
+            public void handle(DragEvent t) {
+
+                Dragboard db = t.getDragboard();
+
+                if (db.hasImage()) {
+                    t.acceptTransferModes(TransferMode.COPY);
+                }
+                t.consume();
+            }
+        });
+
+        pane.setOnDragDropped(new EventHandler<DragEvent>() {
+            @Override
+            public void handle(DragEvent event) {
+
+                Dragboard db = event.getDragboard();
+
+                if (db.hasImage()) {
+
+                    insertImage(db.getImage(), pane, event.getX(), event.getY());
+
+                    event.setDropCompleted(true);
+                } else {
+                    event.setDropCompleted(false);
+                }
+                event.consume();
+            }
+        });
+
+        SingleSelectionModel<Tab> tab = topologyNewCanvas.getSelectionModel();
+        tab.getSelectedItem().getContent().setOnMouseClicked(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent arg0) {
+                SingleSelectionModel<Tab> tab1 = topologyNewCanvas.getSelectionModel();
+            }
+        });
+
+        topologyBox.getChildren().addAll(topologyPane, topologyNewCanvas);
+        parentTopologyBox.getChildren().addAll(canvasToolBar, topologyBox);
+        return parentTopologyBox;
+    }
+
+    void insertImage(Image i, final Pane hb, double x, double y) {
+        final TextField text = new TextField();
+        final String[] deviceInfo;;
+        text.setId(driverExplorerTreeView.getSelectionModel().getSelectedItem().getValue().toString() + "_" + driverExplorerTreeView.getSelectionModel().getSelectedItem().getParent().getValue());
+        deviceInfo = text.getId().split("\\_");
+        deviceNameList.add(text);
+        text.setPrefWidth(100);
+        ImageView iv = new ImageView();
+        iv.setImage(i);
+
+        final DraggableNode content = new DraggableNode();
+        final VBox hbox = new VBox();
+        hbox.setPrefWidth(80);
+        hbox.setPrefHeight(100);
+        lineButtonHorizontal.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent arg0) {
+                final Line connecting = new Line(33, 43, 33, 43);
+                connecting.setId("Line");
+                connecting.setStrokeLineCap(StrokeLineCap.ROUND);
+                connecting.setStroke(Color.MIDNIGHTBLUE);
+                connecting.setStrokeWidth(2.5);
+                final TopologyWizard.Anchor anchor1 = new TopologyWizard.Anchor("Anchor 1", connecting.startXProperty(), connecting.startYProperty());
+                final TopologyWizard.Anchor anchor2 = new TopologyWizard.Anchor("Anchor 2", connecting.endXProperty(), connecting.endYProperty());
+                anchor1.setFill(Color.TRANSPARENT.deriveColor(1, 1, 1, 0.5));
+                anchor2.setFill(Color.TRANSPARENT.deriveColor(1, 1, 1, 0.5));
+                Circle[] circles = {anchor1, anchor2};
+                for (Circle circle : circles) {
+                    enableDrag(circle);
+                }
+                enableDragLineWithAnchors(connecting, anchor1, anchor2);
+
+                anchor1.setOnMouseEntered(new EventHandler<MouseEvent>() {
+                    @Override
+                    public void handle(MouseEvent arg0) {
+                        anchor1.setFill(Color.GOLD.deriveColor(1, 1, 1, 0.5));
+                        anchor1.setVisible(true);
+                        anchor2.setVisible(true);
+                    }
+                });
+
+                anchor1.setOnMouseExited(new EventHandler<MouseEvent>() {
+                    @Override
+                    public void handle(MouseEvent arg0) {
+                        anchor1.setFill(Color.TRANSPARENT.deriveColor(1, 1, 1, 0.5));
+                        anchor1.setVisible(false);
+                        anchor2.setVisible(false);
+                    }
+                });
+
+                anchor2.setOnMouseEntered(new EventHandler<MouseEvent>() {
+                    @Override
+                    public void handle(MouseEvent arg0) {
+                        anchor2.setFill(Color.GOLD.deriveColor(1, 1, 1, 0.5));
+                        anchor1.setVisible(true);
+                        anchor2.setVisible(true);
+                    }
+                });
+
+                anchor2.setOnMouseExited(new EventHandler<MouseEvent>() {
+                    @Override
+                    public void handle(MouseEvent arg0) {
+                        anchor2.setFill(Color.TRANSPARENT.deriveColor(1, 1, 1, 0.5));
+                        anchor1.setVisible(false);
+                        anchor2.setVisible(false);
+                    }
+                });
+
+                connecting.setOnMouseEntered(new EventHandler<MouseEvent>() {
+                    @Override
+                    public void handle(MouseEvent arg0) {
+                        connecting.setStroke(Color.GOLD);
+                        anchor1.setVisible(true);
+                        anchor2.setVisible(true);
+                    }
+                });
+                connecting.setOnMouseExited(new EventHandler<MouseEvent>() {
+                    @Override
+                    public void handle(MouseEvent arg0) {
+                        connecting.setStroke(Color.MIDNIGHTBLUE);
+                        anchor1.setVisible(false);
+                        anchor2.setVisible(false);
+
+                    }
+                });
+
+                final DraggableNode contentLine = new DraggableNode();
+
+                connecting.setOnMouseClicked(new EventHandler<MouseEvent>() {
+                    @Override
+                    public void handle(MouseEvent arg0) {
+                        if (arg0.getClickCount() == 2) {
+
+                            topologyLink.start(new Stage());
+
+                            if (arrayOfLinkTopologyHash.isEmpty()) {
+                                for (HashMap<String, String> linkHash : arrayOfLinkTopologyHash) {
+                                    Set linkSet = linkHash.entrySet();
+                                    Iterator linkHashDetailIterator = linkSet.iterator();
+                                    while (linkHashDetailIterator.hasNext()) {
+
+                                        Map.Entry linkMap = (Map.Entry) linkHashDetailIterator.next();
+
+                                        if (linkMap.getKey().toString().equals(connecting.getId())) {
+                                            String[] linkValues = linkMap.getValue().toString().split("_");
+
+                                            topologyLink.nameText.setText(linkValues[0]);
+                                            topologyLink.typeText.setText(linkValues[1]);
+                                            topologyLink.devicesInTopoEditor.setEditable(true);
+                                            topologyLink.devicesInTopoEditor.getSelectionModel().select(linkValues[2]);
+                                            topologyLink.interfaceList2.setEditable(true);
+                                            topologyLink.interfaceList2.getSelectionModel().select(linkValues[3]);
+                                            topologyLink.destDevicesInTopoEditor.setEditable(true);
+                                            topologyLink.destDevicesInTopoEditor.getSelectionModel().select(linkValues[4]);
+                                            topologyLink.interfaceList4.setEditable(true);
+                                            topologyLink.interfaceList4.getSelectionModel().select(linkValues[5]);
+
+                                        }
+                                    }
+                                }
+                            }
+
+                            for (String string : draggedImagesName) {
+                                topologyLink.devicesInTopoEditor.getItems().add(string);
+                                topologyLink.destDevicesInTopoEditor.getItems().add(string);
+                            }
+
+                            topologyLink.devicesInTopoEditor.setOnAction(new EventHandler<ActionEvent>() {
+                                @Override
+                                public void handle(ActionEvent arg0) {
+                                    topologyLink.interfaceList2.getItems().clear();
+                                    try {
+                                        for (HashMap<String, String> interFaceDetail : arrayOfInterFaceHash) {
+                                            Set set = interFaceDetail.entrySet();
+                                            Iterator interFaceHashDetailIterator = set.iterator();
+                                            while (interFaceHashDetailIterator.hasNext()) {
+                                                Map.Entry me = (Map.Entry) interFaceHashDetailIterator.next();
+
+                                                String[] deviceNameAndiniterFaceValue = me.getValue().toString().split("\\_");
+
+                                                if (deviceNameAndiniterFaceValue[1].equals(topologyLink.devicesInTopoEditor.getSelectionModel().getSelectedItem())) {
+                                                    if (!me.getKey().toString().equals("")) {
+                                                        topologyLink.interfaceList2.getItems().add(me.getKey().toString());
+
+                                                    }
+                                                }
+
+                                            }
+                                        }
+                                    } catch (Exception e) {
+                                    }
+                                }
+                            });
+
+                            topologyLink.destDevicesInTopoEditor.setOnAction(new EventHandler<ActionEvent>() {
+                                @Override
+                                public void handle(ActionEvent arg0) {
+                                    topologyLink.interfaceList4.getItems().clear();
+                                    try {
+                                        for (HashMap<String, String> interFaceDetail : arrayOfInterFaceHash) {
+                                            Set set = interFaceDetail.entrySet();
+                                            Iterator interFaceHashDetailIterator = set.iterator();
+                                            while (interFaceHashDetailIterator.hasNext()) {
+                                                Map.Entry me = (Map.Entry) interFaceHashDetailIterator.next();
+                                                String[] deviceNameAndiniterFaceValue = me.getValue().toString().split("\\_");
+                                                if (deviceNameAndiniterFaceValue[1].equals(topologyLink.destDevicesInTopoEditor.getSelectionModel().getSelectedItem())) {
+                                                    if (!me.getKey().toString().equals("")) {
+                                                        topologyLink.interfaceList4.getItems().add(me.getKey().toString());
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    } catch (Exception e) {
+                                    }
+                                }
+                            });
+
+                            topologyLink.finishSelectedLink.setOnAction(new EventHandler<ActionEvent>() {
+                                @Override
+                                public void handle(ActionEvent arg0) {
+                                    connecting.setId(topologyLink.nameText.getText() + "_" + connecting.getStartX() + "_" + connecting.getStartY() + "_" + connecting.getEndX() + "_" + connecting.getEndY());
+                                    String detailedString = topologyLink.nameText.getText() + "_" + topologyLink.typeText.getText() + "_" + topologyLink.devicesInTopoEditor.getSelectionModel().getSelectedItem() + "_" + topologyLink.interfaceList2.getSelectionModel().getSelectedItem() + "_" + topologyLink.destDevicesInTopoEditor.getSelectionModel().getSelectedItem() + "_" + topologyLink.interfaceList4.getSelectionModel().getSelectedItem() + "_";
+                                    linkTopologyHash.put(connecting.getId(), detailedString);
+                                    arrayOfLinkTopologyHash = new ArrayList<HashMap<String, String>>();
+                                    arrayOfLinkTopologyHash.add(linkTopologyHash);
+                                    topologyLink.copyStage.close();
+                                }
+                            });
+                        } else if (arg0.getButton() == MouseButton.SECONDARY) {
+                            deleteLineContextMenu(contentLine, connecting, arg0);
+                        }
+                    }
+                });
+                hb.getChildren().addAll(connecting, anchor1, anchor2);
+            }
+        });
+
+        content.setOnMouseClicked(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent arg0) {
+                if (anchorFlag == false) {
+                    if (arg0.getClickCount() == 1) {
+                        final Line con = new Line();
+                        con.setStrokeLineCap(StrokeLineCap.ROUND);
+                        con.setStroke(Color.MIDNIGHTBLUE);
+                        con.setStrokeWidth(2.0);
+
+                        final Line con1 = new Line();
+                        con1.setStrokeLineCap(StrokeLineCap.ROUND);
+                        con1.setStroke(Color.MIDNIGHTBLUE);
+                        con1.setStrokeWidth(2.0);
+
+                        final Line con2 = new Line();
+                        con2.setStrokeLineCap(StrokeLineCap.ROUND);
+                        con2.setStroke(Color.MIDNIGHTBLUE);
+                        con2.setStrokeWidth(2.0);
+
+                        final Line con3 = new Line();
+                        con3.setStrokeLineCap(StrokeLineCap.ROUND);
+                        con3.setStroke(Color.MIDNIGHTBLUE);
+                        con3.setStrokeWidth(2.0);
+
+                        OFAAnchorInsideImageNode mainAnchor = new OFAAnchorInsideImageNode(226.0, 41.0);
+                        final Anchor anchor3 = new Anchor("anchor3", con.startXProperty(), con.startYProperty());
+                        final Anchor anchor4 = new Anchor("anchor4", con.endXProperty(), con.endYProperty());
+                        final Anchor anchor5 = new Anchor("anchor5", con1.startXProperty(), con1.startYProperty());
+                        final Anchor anchor6 = new Anchor("anchor6", con1.endXProperty(), con1.endYProperty());
+                        final Anchor anchor7 = new Anchor("anchor7", con2.startXProperty(), con2.startYProperty());
+                        final Anchor anchor8 = new Anchor("anchor8", con2.endXProperty(), con2.endYProperty());
+                        final Anchor anchor9 = new Anchor("anchor9", con3.startXProperty(), con3.startYProperty());
+                        final Anchor anchor10 = new Anchor("anchor10", con3.endXProperty(), con3.endYProperty());
+                        anchor3.setLayoutX(content.getLayoutX());
+                        anchor3.setLayoutY(content.getLayoutY());
+                        anchor3.setVisible(false);
+                        anchor4.setLayoutX(content.getLayoutX() + 40);
+                        anchor4.setLayoutY(content.getLayoutY());
+                        anchor5.setLayoutX(content.getLayoutX());
+                        anchor5.setLayoutY(content.getLayoutY());
+                        anchor5.setVisible(false);
+                        anchor6.setLayoutX(content.getLayoutX() + 40);
+                        anchor6.setLayoutY(content.getLayoutY() + 100);
+                        anchor7.setLayoutX(content.getLayoutX());
+                        anchor7.setLayoutY(content.getLayoutY());
+                        anchor7.setVisible(false);
+                        anchor8.setLayoutX(content.getLayoutX());
+                        anchor8.setLayoutY(content.getLayoutY() + 50);
+                        anchor9.setLayoutX(content.getLayoutX());
+                        anchor9.setLayoutY(content.getLayoutY());
+                        anchor9.setVisible(false);
+                        anchor10.setLayoutX(content.getLayoutX() + 80);
+                        anchor10.setLayoutY(content.getLayoutY() + 50);
+
+                        con1.setLayoutX(anchor6.getLayoutX());
+                        con1.setLayoutY(anchor6.getLayoutY());
+                        con.setLayoutX(anchor4.getLayoutX());
+                        con.setLayoutY(anchor4.getLayoutY());
+                        con2.setLayoutX(anchor8.getLayoutX());
+                        con2.setLayoutY(anchor8.getLayoutY());
+                        con3.setLayoutX(anchor10.getLayoutX());
+                        con3.setLayoutY(anchor10.getLayoutY());
+
+                        con.setId("connectingLine");
+                        con.setLayoutX(anchor4.getLayoutX());
+                        con.setLayoutY(anchor4.getLayoutY());
+
+                        anchorFlag = true;
+                        hb.getChildren().addAll(con, anchor3, anchor4, con1, anchor5, anchor6, con2, anchor7, anchor8, con3, anchor9, anchor10);
+                        HashMap<Node, String> anchorNodeHash = new HashMap();
+
+                        anchorNodeHash.put(anchor4, anchor4.getId());
+                        anchorNodeHash.put(anchor6, anchor6.getId());
+                        anchorNodeHash.put(anchor8, anchor8.getId());
+                        anchorNodeHash.put(anchor10, anchor10.getId());
+                        anchorNodeHash.put(con1, con1.getId());
+                        anchorNodeHash.put(con2, con2.getId());
+                        anchorNodeHash.put(con3, con3.getId());
+                        anchorNodeHash.put(con, con.getId());
+
+                        final ObservableList<Node> allNodeInCanvas = hb.getChildren();
+                        mainAnchor.anchorsInsideImage(anchor4, 40, 0, 40, 100, hb, content, hbox, con, draggedImagesName, arrayOfInterFaceHash, linkTopologyHash, anchorNodeHash);
+                        mainAnchor.anchorsInsideImage(anchor6, 40, 100, 40, 0, hb, content, hbox, con, draggedImagesName, arrayOfInterFaceHash, linkTopologyHash, anchorNodeHash);
+                        mainAnchor.anchorsInsideImage(anchor8, 0, 50, 80, 50, hb, content, hbox, con, draggedImagesName, arrayOfInterFaceHash, linkTopologyHash, anchorNodeHash);
+                        mainAnchor.anchorsInsideImage(anchor10, 80, 50, 0, 50, hb, content, hbox, con, draggedImagesName, arrayOfInterFaceHash, linkTopologyHash, anchorNodeHash);
+
+                        hbox.setOnDragDetected(new EventHandler<MouseEvent>() {
+                            @Override
+                            public void handle(MouseEvent t) {
+                                hbox.startFullDrag();
+                            }
+                        });
+
+                        hbox.setOnMouseDragged(new EventHandler<MouseEvent>() {
+                            @Override
+                            public void handle(MouseEvent t) {
+                                anchorFlag = false;
+                                hb.getChildren().removeAll(con, con1, con2, con3, anchor4, anchor6, anchor8, anchor10);
+                            }
+                        });
+
+                        content.setOnMouseMoved(new EventHandler<MouseEvent>() {
+                            @Override
+                            public void handle(MouseEvent arg0) {
+                                Double x13 = content.getScene().getX() + 482.0 + 53.0;
+                                Double x14 = content.getLayoutX() + 482.0;
+                                Double y13 = content.getScene().getY() + 142.0 + 92.0;
+                                Double y14 = content.getLayoutY() + 142.0;
+                                boolean exitFlag = false;
+                                for (int i = 0; i <= 80; i++) {
+                                    for (int j = 0; j <= 100; j++) {
+                                        Double x1 = content.getScene().getX();
+                                        Double y1 = content.getScene().getX();
+                                        Double x11 = x1 + i;
+                                        Double y11 = y1 + j;
+                                        if (x11 == arg0.getSceneX()) {
+                                            if (y11 == arg0.getSceneY()) {
+                                                exitFlag = true;
+                                            }
+                                        }
+                                    }
+                                }
+
+                                if (exitFlag == false) {
+                                    anchorFlag = false;
+                                    hb.getChildren().removeAll(con, con1, con2, con3, anchor4, anchor5, anchor6, anchor7, anchor8, anchor9, anchor10);
+                                }
+                            }
+                        });
+
+                    }
+                }
+
+                if (arg0.getClickCount() == 2) {
+                    if (deviceInfo[0].equals("fvtapidriver") || deviceInfo[0].equals("poxclidriver") || deviceInfo[0].equals("mininetclidriver") || deviceInfo[0].equals("dpctlclidriver")
+                            || deviceInfo[0].equals("floodlightclidriver") || deviceInfo[0].equals("flowvisorclidriver") || deviceInfo[0].equals("hpswitchclidriver")
+                            || deviceInfo[0].equals("remotevmdriver") || deviceInfo[0].equals("remotepoxdriver") || deviceInfo[0].equals("flowvisordriver") || deviceInfo[0].equals("switchclidriver")) {
+                        try {
+                            topoplogy = new OFATopology();
+                            topoplogy.start(new Stage());
+                        } catch (Exception ex) {
+                            Logger.getLogger(TopologyWizard.class.getName()).log(Level.SEVERE, null, ex);
+                        }
+
+                        if (topoplogy.testTargetRadioButton.isSelected()) {
+                            selectFlag = true;
+                        }
+
+                        topoplogy.cancelButton.setOnAction(new EventHandler<ActionEvent>() {
+                            @Override
+                            public void handle(ActionEvent arg0) {
+                                topoplogy.copyStage.close();
+                            }
+                        });
+                        
+                        topoplogy.save.setOnAction(new EventHandler<ActionEvent>() {
+                            @Override
+                            public void handle(ActionEvent arg0) {
+                                topoplogy.getHostName = topoplogy.hostNameText.getText();
+                                topoplogy.getUserName = topoplogy.userNameText.getText();
+                                topoplogy.getPassword = topoplogy.passwordText.getText();
+
+                                for (int i = 0; i < topoplogy.deviceTable.getItems().size(); i++) {
+                                    topoplogy.deviceTable.getSelectionModel().select(i);
+                                    interFaceHashDetail.put(topoplogy.deviceTable.getSelectionModel().getSelectedItem().getDeviceName().getText(), topoplogy.deviceTable.getSelectionModel().getSelectedItem().getDeviceType().getText() + "_" + text.getText());
+                                    arrayOfInterFaceHash = new ArrayList<HashMap<String, String>>();
+                                    arrayOfInterFaceHash.add(interFaceHashDetail);
+                                }
+
+                                draggedImagesName.add(text.getText());
+                                propertyValue.add(text.getText() + "\n" + topoplogy.getHostName + "\n" + topoplogy.getUserName + "\n" + topoplogy.getPassword + "\n" + topoplogy.getTranportProtocol + "\n" + deviceInfo[0] + "\n" + topoplogy.getPort + "\n" + content.getId());
+                                topoplogy.copyStage.close();
+                            }
+                        });
+                    }
+                    if (deviceInfo[1].equals("cli") || deviceInfo[1].equals("poxclidriver") || deviceInfo[1].equals("mininetclidriver") || deviceInfo[1].equals("dpctlclidriver")
+                            || deviceInfo[1].equals("floodlightclidriver") || deviceInfo[1].equals("flowvisorclidriver") || deviceInfo[1].equals("hpswitchclidriver")
+                            || deviceInfo[1].equals("remotevmdriver") || deviceInfo[1].equals("remotepoxdriver") || deviceInfo[1].equals("flowvisordriver") || deviceInfo[1].equals("switchclidriver")) {
+                        try {
+                            topoplogy = new OFATopology();
+                            topoplogy.start(new Stage());
+                        } catch (Exception ex) {
+                            Logger.getLogger(TopologyWizard.class.getName()).log(Level.SEVERE, null, ex);
+                        }
+
+                        topoplogy.cancelButton.setOnAction(new EventHandler<ActionEvent>() {
+                            @Override
+                            public void handle(ActionEvent arg0) {
+                                topoplogy.copyStage.close();
+                            }
+                        });
+                    
+                        try {
+                            topoplogy.save.setOnAction(new EventHandler<ActionEvent>() {
+                                @Override
+                                public void handle(ActionEvent arg0) {
+                                    topoplogy.getHostName = topoplogy.hostNameText.getText();
+                                    topoplogy.getUserName = topoplogy.userNameText.getText();
+                                    topoplogy.getPassword = topoplogy.passwordText.getText();
+                                    for (int i = 0; i < topoplogy.deviceTable.getItems().size(); i++) {
+                                        topoplogy.deviceTable.getSelectionModel().select(i);
+                                        interFaceHashDetail.put(topoplogy.deviceTable.getSelectionModel().getSelectedItem().getDeviceName().getText(), topoplogy.deviceTable.getSelectionModel().getSelectedItem().getDeviceType().getText() + "_" + text.getText());
+                                        arrayOfInterFaceHash = new ArrayList<HashMap<String, String>>();
+                                        arrayOfInterFaceHash.add(interFaceHashDetail);
+                                    }
+                                    draggedImagesName.add(text.getText());
+                                    propertyValue.add(text.getText() + "\n" + topoplogy.getHostName + "\n" + topoplogy.getUserName + "\n" + topoplogy.getPassword + "\n" + topoplogy.getTranportProtocol + "\n" + deviceInfo[0] + "\n" + topoplogy.getPort + "\n" + content.getId());
+                                    topoplogy.copyStage.close();
+                                }
+                            });
+                        } catch (Exception e) {
+                        }
+                    }
+
+                }
+            }
+        });
+
+        final Button closeButton = new Button();
+        Tooltip close = new Tooltip();
+        close.setText("Delete this device");
+        closeButton.setTooltip(close);
+        Image image = new Image(getClass().getResourceAsStream("/images/close_icon2.jpg"), 12, 12, true, true);
+        ImageView imageNew3 = new ImageView(image);
+        closeButton.setGraphic(imageNew3);
+        closeButton.setStyle("-fx-background-color: white;");
+
+        final ArrayList<Node> removeNodes = new ArrayList<Node>();
+        closeButton.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent arg0) {
+                OFAAnchorInsideImageNode node = new OFAAnchorInsideImageNode(224.0, 41.0);
+                node.closeNodeOnCanvas(closeButton, hbox, hb, content);
+                Node parent = hbox.getParent();
+                ObservableList<Node> allCurrentNode = hb.getChildren();
+                for (Node node1 : allCurrentNode) {
+                    if (node1.toString().contains("Line")) {
+                        if (!node1.toString().matches("Line[id=Line[id=null,null]]")) {
+                            if (node1.getId() != null) {
+                                String[] startLineNode = node1.getId().split(",");
+                                Integer nodeHash = content.hashCode();
+
+                                if (nodeHash.toString().equals(startLineNode[0])) {
+                                    removeNodes.add(node1);
+                                }
+
+                                if (startLineNode.length == 2) {
+                                    if (nodeHash.toString().equals(startLineNode[1])) {
+                                        removeNodes.add(node1);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+
+                for (Node removenode : removeNodes) {
+                    hb.getChildren().remove(removenode);
+                }
+
+                hb.getChildren().remove(content);
+
+            }
+        });
+
+        hbox.getChildren().addAll(closeButton, iv, text);
+        hbox.setId(iv.toString());
+
+        text.setPromptText("Device Name");
+        content.getChildren().add(hbox);
+
+        content.setOnMouseEntered(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent arg0) {
+                hbox.setStyle("-fx-border-color: Gold");
+            }
+        });
+
+        content.setOnMouseExited(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent arg0) {
+                hbox.setStyle("-fx-border-color: Transparent");
+                Double xcoordinate = content.getLayoutX();
+                Double ycoordinate = content.getLayoutY();
+                OFATopology device = new OFATopology();
+
+                content.setId(xcoordinate.toString() + "," + ycoordinate.toString());
+            }
+        });
+
+        content.setLayoutX(x - 40);
+        content.setLayoutY(y - 30);
+        hb.getChildren().add(content);
+    }
+
+    void anchorsInsideImageNode(final Anchor anchor, final double bindLinex, final double bindLiney, final Pane hb, final DraggableNode content, final VBox hbox, final Line con) {
+
+
+        final Line con11 = new Line();
+
+        anchor.setOnDragDetected(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent arg0) {
+                anchor.startFullDrag();
+                enableDrag(anchor);
+            }
+        });
+
+        anchor.setOnMouseExited(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent arg0) {
+
+                boolean exitFlag = false;
+                for (int i = 0; i <= 80; i++) {
+                    for (int j = 0; j <= 100; j++) {
+                        Double x1 = anchor.getLayoutX() + 482.0;
+                        Double y1 = anchor.getLayoutY() + 142.0;
+                        Double x11 = x1 + i;
+                        Double y11 = y1 + j;
+                        if (x11 == arg0.getSceneX()) {
+                            if (y11 == arg0.getSceneY()) {
+                                exitFlag = true;
+
+                            }
+                        }
+                    }
+                }
+                if (exitFlag == false) {
+                    hbox.setStyle("-fx-border-color: Transparent");
+                    anchor.setVisible(false);
+                    con.setVisible(false);
+
+                }
+            }
+        });
+
+        hbox.setOnMouseDragged(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent arg0) {
+                try {
+                    con.setVisible(false);
+                    anchor.setVisible(false);
+                    hb.getChildren().removeAll(con, anchor);
+                } catch (Exception e) {
+                }
+
+            }
+        });
+
+        anchor.setOnMouseDragReleased(new EventHandler<MouseDragEvent>() {
+            @Override
+            public void handle(MouseDragEvent arg0) {
+
+                ObservableList<Node> allNodesCanvas = hb.getChildren();
+                boolean flag = false;
+                try {
+                    for (Node node : allNodesCanvas) {
+
+                        Double x = node.getLayoutX() + 226.0;
+                        Double y = node.getLayoutY() + 41.0;
+
+                        if (node.toString().startsWith("DraggableNode")) {
+                            for (int i = 0; i <= 80; i++) {
+                                for (int j = 0; j <= 100; j++) {
+                                    Double x1 = node.getLayoutX() + 226.0;
+                                    Double y1 = node.getLayoutY() + 41.0;
+                                    Double x11 = x1 + i;
+                                    Double y11 = y1 + j;
+                                    if (x11 == arg0.getSceneX()) {
+                                        if (y11 == arg0.getSceneY()) {
+                                            con11.setStrokeLineCap(StrokeLineCap.ROUND);
+                                            con11.setStroke(Color.MIDNIGHTBLUE);
+                                            con11.setStrokeWidth(2.0);
+                                            con11.startXProperty().bind(content.layoutXProperty().add(bindLinex));
+                                            con11.startYProperty().bind(content.layoutYProperty().add(bindLiney));
+                                            con11.endXProperty().bind(node.layoutXProperty().add(bindLinex));
+                                            con11.endYProperty().bind(node.layoutYProperty().add(bindLiney));
+
+                                            hbox.setStyle("-fx-border-color: Transparent");
+
+                                            hb.getChildren().add(con11);
+                                            con.setVisible(false);
+                                            anchor.setVisible(false);
+                                            flag = true;
+
+                                        }
+
+                                    }
+                                }
+                            }
+
+                        }
+
+                    }
+                    if (flag == false) {
+                        con.setVisible(false);
+                        anchor.setVisible(false);
+                    }
+                } catch (Exception e) {
+                    
+                }
+
+            }
+        });
+
+        con11.setOnMouseEntered(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent arg0) {
+
+                con11.setStroke(Color.GOLD);
+
+            }
+        });
+        con11.setOnMouseExited(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent arg0) {
+
+                con11.setStroke(Color.MIDNIGHTBLUE);
+            }
+        });
+
+        final DraggableNode contentLine = new DraggableNode();
+        con11.setOnMouseClicked(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent arg0) {
+                if (arg0.getClickCount() == 2) {
+
+                    topologyLink.start(new Stage());
+
+                    if (arrayOfLinkTopologyHash.isEmpty()) {
+                        for (HashMap<String, String> linkHash : arrayOfLinkTopologyHash) {
+                            Set linkSet = linkHash.entrySet();
+                            Iterator linkHashDetailIterator = linkSet.iterator();
+                            while (linkHashDetailIterator.hasNext()) {
+
+                                Map.Entry linkMap = (Map.Entry) linkHashDetailIterator.next();
+                                if (linkMap.getKey().toString().equals(con11.getId())) {
+                                    String[] linkValues = linkMap.getValue().toString().split("_");
+                                    topologyLink.nameText.setText(linkValues[0]);
+                                    topologyLink.typeText.setText(linkValues[1]);
+                                    topologyLink.devicesInTopoEditor.setEditable(true);
+                                    topologyLink.devicesInTopoEditor.getSelectionModel().select(linkValues[2]);
+                                    topologyLink.interfaceList2.setEditable(true);
+                                    topologyLink.interfaceList2.getSelectionModel().select(linkValues[3]);
+                                    topologyLink.destDevicesInTopoEditor.setEditable(true);
+                                    topologyLink.destDevicesInTopoEditor.getSelectionModel().select(linkValues[4]);
+                                    topologyLink.interfaceList4.setEditable(true);
+                                    topologyLink.interfaceList4.getSelectionModel().select(linkValues[5]);
+                                }
+                            }
+                        }
+                    }
+
+                    for (String string : draggedImagesName) {
+                        topologyLink.devicesInTopoEditor.getItems().add(string);
+                        topologyLink.destDevicesInTopoEditor.getItems().add(string);
+                    }
+
+                    topologyLink.devicesInTopoEditor.setOnAction(new EventHandler<ActionEvent>() {
+                        @Override
+                        public void handle(ActionEvent arg0) {
+                            topologyLink.interfaceList2.getItems().clear();
+                            try {
+                                for (HashMap<String, String> interFaceDetail : arrayOfInterFaceHash) {
+                                    Set set = interFaceDetail.entrySet();
+                                    Iterator interFaceHashDetailIterator = set.iterator();
+                                    while (interFaceHashDetailIterator.hasNext()) {
+                                        Map.Entry me = (Map.Entry) interFaceHashDetailIterator.next();
+                                        String[] deviceNameAndiniterFaceValue = me.getValue().toString().split("\\_");
+                                        if (deviceNameAndiniterFaceValue[1].equals(topologyLink.devicesInTopoEditor.getSelectionModel().getSelectedItem())) {
+                                            if (!me.getKey().toString().equals("")) {
+                                                topologyLink.interfaceList2.getItems().add(me.getKey().toString());
+                                            }
+                                        }
+                                    }
+                                }
+                            } catch (Exception e) {
+                            }
+                        }
+                    });
+
+                    topologyLink.destDevicesInTopoEditor.setOnAction(new EventHandler<ActionEvent>() {
+                        @Override
+                        public void handle(ActionEvent arg0) {
+
+                            topologyLink.interfaceList4.getItems().clear();
+                            try {
+                                for (HashMap<String, String> interFaceDetail : arrayOfInterFaceHash) {
+                                    Set set = interFaceDetail.entrySet();
+                                    Iterator interFaceHashDetailIterator = set.iterator();
+                                    while (interFaceHashDetailIterator.hasNext()) {
+                                        Map.Entry me = (Map.Entry) interFaceHashDetailIterator.next();
+                                        String[] deviceNameAndiniterFaceValue = me.getValue().toString().split("\\_");
+
+                                        if (deviceNameAndiniterFaceValue[1].equals(topologyLink.destDevicesInTopoEditor.getSelectionModel().getSelectedItem())) {
+                                            if (!me.getKey().toString().equals("")) {
+                                                topologyLink.interfaceList4.getItems().add(me.getKey().toString());
+                                            }
+                                        }
+                                    }
+                                }
+                            } catch (Exception e) {
+                            }
+                        }
+                    });
+
+                    topologyLink.finishSelectedLink.setOnAction(new EventHandler<ActionEvent>() {
+                        @Override
+                        public void handle(ActionEvent arg0) {
+                            con11.setId(topologyLink.nameText.getText() + "_" + con11.getStartX() + "_" + con11.getStartY() + "_" + con11.getEndX() + "_" + con11.getEndY());
+                            String detailedString = topologyLink.nameText.getText() + "_" + topologyLink.typeText.getText() + "_" + topologyLink.devicesInTopoEditor.getSelectionModel().getSelectedItem() + "_" + topologyLink.interfaceList2.getSelectionModel().getSelectedItem() + "_" + topologyLink.destDevicesInTopoEditor.getSelectionModel().getSelectedItem() + "_" + topologyLink.interfaceList4.getSelectionModel().getSelectedItem() + "_";
+                            linkTopologyHash.put(con11.getId(), detailedString);
+                            arrayOfLinkTopologyHash = new ArrayList<HashMap<String, String>>();
+                            arrayOfLinkTopologyHash.add(linkTopologyHash);
+                            topologyLink.copyStage.close();
+                        }
+                    });
+
+
+                }
+                if (arg0.getButton() == MouseButton.SECONDARY) {
+                    deleteLineContextMenu(contentLine, con11, arg0);
+
+                }
+            }
+        });
+
+    }
+
+    void insertImage1(Image i, Tab hb) {
+        ImageView iv = new ImageView();
+        iv.setImage(i);
+        setupGestureSource(iv);
+    }
+
+    void setupGestureTarget(final HBox targetBox) {
+        targetBox.setOnDragOver(new EventHandler<DragEvent>() {
+            @Override
+            public void handle(DragEvent event) {
+                Dragboard db = event.getDragboard();
+                if (db.hasImage()) {
+                    event.acceptTransferModes(TransferMode.COPY);
+                }
+                event.consume();
+            }
+        });
+
+        targetBox.setOnDragDropped(new EventHandler<DragEvent>() {
+            @Override
+            public void handle(DragEvent event) {
+               Dragboard db = event.getDragboard();
+                if (db.hasImage()) {
+                    event.setDropCompleted(true);
+                } else {
+                    event.setDropCompleted(false);
+                }
+                event.consume();
+            }
+        });
+    }
+
+    void setupGestureSource(final ImageView source) {
+        source.setOnDragDetected(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent event) {
+
+                /*
+                 * allow any transfer mode
+                 */
+                Dragboard db = source.startDragAndDrop(TransferMode.COPY);
+
+                /*
+                 * put a image on dragboard
+                 */
+                ClipboardContent content = new ClipboardContent();
+
+                Image sourceImage = source.getImage();
+                content.putImage(sourceImage);
+                db.setContent(content);
+
+                event.consume();
+            }
+        });
+
+    }
+
+    void deleteLineContextMenu(final DraggableNode contentLine, final Line connecting, MouseEvent arg0) {
+
+        ContextMenu menu = new ContextMenu();
+        MenuItem item = new MenuItem("Delete Line");
+        item.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent arg0) {
+                contentLine.setVisible(false);
+                contentLine.getChildren().remove(connecting);
+            }
+        });
+
+        menu.getItems().add(item);
+        menu.show(contentLine, arg0.getScreenX(), arg0.getScreenY());
+
+    }
+
+    public ArrayList<TextField> getDeviceNameList() {
+        return deviceNameList;
+    }
+
+    public ArrayList<String> getPropertyDetail() {
+        return propertyValue;
+    }
+
+    class Anchor extends Circle {
+
+        Anchor(String id, DoubleProperty x, DoubleProperty y) {
+            super(x.get(), y.get(), 7);
+            setId(id);
+            setFill(Color.ANTIQUEWHITE.deriveColor(1, 1, 1, 0.75));
+            setStroke(Color.GREY);
+            x.bind(centerXProperty());
+            y.bind(centerYProperty());
+        }
+    }
+
+    class Anchor2 extends DraggableNode {
+
+        Anchor2(String id, DoubleProperty x, DoubleProperty y) {
+            super();
+            setId(id);
+
+            x.bind(layoutXProperty());
+            y.bind(layoutYProperty());
+        }
+    }
+
+    private void enableDragLineWithAnchors(final Line connecting, final Circle anchor1, final Circle anchor2) {
+        final Delta dragDelta = new Delta();
+
+        connecting.setOnMousePressed(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent mouseEvent) {
+                // record a delta distance for the drag and drop operation.
+                dragDelta.x = connecting.getLayoutX() - mouseEvent.getX();
+                dragDelta.y = connecting.getLayoutY() - mouseEvent.getY();
+                dragDelta.x = anchor1.getLayoutX() - mouseEvent.getX();
+                dragDelta.y = anchor1.getLayoutY() - mouseEvent.getY();
+                dragDelta.x = anchor2.getLayoutX() - mouseEvent.getX();
+                dragDelta.y = anchor2.getLayoutY() - mouseEvent.getY();
+                connecting.getScene().setCursor(Cursor.MOVE);
+            }
+        });
+        connecting.setOnMouseReleased(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent mouseEvent) {
+                connecting.getScene().setCursor(Cursor.HAND);
+            }
+        });
+        connecting.setOnMouseDragged(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent mouseEvent) {
+                connecting.setLayoutX(mouseEvent.getX() + dragDelta.x);
+                connecting.setLayoutY(mouseEvent.getY() + dragDelta.y);
+                anchor1.setLayoutX(mouseEvent.getX() + dragDelta.x);
+                anchor1.setLayoutY(mouseEvent.getY() + dragDelta.y);
+                anchor2.setLayoutX(mouseEvent.getX() + dragDelta.x);
+                anchor2.setLayoutY(mouseEvent.getY() + dragDelta.y);
+
+            }
+        });
+        connecting.setOnMouseEntered(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent mouseEvent) {
+                if (!mouseEvent.isPrimaryButtonDown()) {
+                    connecting.getScene().setCursor(Cursor.HAND);
+                }
+            }
+        });
+
+        connecting.setOnMouseExited(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent mouseEvent) {
+                if (!mouseEvent.isPrimaryButtonDown()) {
+                    connecting.getScene().setCursor(Cursor.DEFAULT);
+                }
+            }
+        });
+    }
+
+    private void enableDrag(final Circle circle) {
+        final TopologyWizard.Delta dragDelta = new TopologyWizard.Delta();
+        circle.setOnMousePressed(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent mouseEvent) {
+                // record a delta distance for the drag and drop operation.
+                dragDelta.x = circle.getCenterX() - mouseEvent.getX();
+                dragDelta.y = circle.getCenterY() - mouseEvent.getY();
+                circle.getScene().setCursor(Cursor.MOVE);
+            }
+        });
+        circle.setOnMouseReleased(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent mouseEvent) {
+                circle.getScene().setCursor(Cursor.HAND);
+            }
+        });
+        circle.setOnMouseDragged(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent mouseEvent) {
+                circle.setCenterX(mouseEvent.getX() + dragDelta.x);
+                circle.setCenterY(mouseEvent.getY() + dragDelta.y);
+            }
+        });
+        circle.setOnMouseEntered(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent mouseEvent) {
+                if (!mouseEvent.isPrimaryButtonDown()) {
+                    circle.getScene().setCursor(Cursor.HAND);
+                }
+            }
+        });
+        circle.setOnMouseExited(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent mouseEvent) {
+                if (!mouseEvent.isPrimaryButtonDown()) {
+                    circle.getScene().setCursor(Cursor.DEFAULT);
+                }
+            }
+        });
+    }
+
+    class Delta {
+
+        double x, y;
+    }
+}
diff --git a/TestON/TAI/src/tai_ofa/StepTable.java b/TestON/TAI/src/tai_ofa/StepTable.java
new file mode 100644
index 0000000..ead5d85
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/StepTable.java
@@ -0,0 +1,63 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package tai_ofa;
+
+import javafx.scene.control.Label;
+
+/**
+ *
+ * @author Raghav Kashyap (raghavkashyap@paxterrasolutions.com)
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+ */
+public class StepTable {
+    public Label testStepId;
+    public Label testStepName;
+    public Label testStepStatus;
+    
+    public StepTable() {
+        
+    }
+    public StepTable(Label stepId, Label stepName,Label status) {
+        
+        this.testStepId = stepId;
+        this.testStepName = stepName;
+        this.testStepStatus = status;
+        
+    }
+    
+  
+     public Label getTestStepId() {
+        return  testStepId;
+    }
+    public void setTestStepId(Label newStepId) {
+        testStepId = newStepId;
+    }
+    public Label getTestStepName() {
+        return  testStepName;
+    }
+    public void setTestCaseName(Label newStepName) {
+        testStepName = newStepName;
+    }
+    public Label getTestStepStatus() {
+        return  testStepStatus;
+    }
+    public void setTestCaseStatus(Label newStepStatus) {
+        testStepStatus = newStepStatus;
+    }
+      
+}
diff --git a/TestON/TAI/src/tai_ofa/SummaryTable.java b/TestON/TAI/src/tai_ofa/SummaryTable.java
new file mode 100644
index 0000000..5c1b1a8
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/SummaryTable.java
@@ -0,0 +1,80 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package tai_ofa;
+
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.Label;
+
+/**
+ *
+ * @author Raghav Kashyap (raghavkashyap@paxterrasolutions.com)
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+ */
+public class SummaryTable {
+    public Label testCaseId;
+    public Label testCaseName;
+    public Label testCaseStatus;
+    public Label testCaseStartTime;
+    public Label testCaseEndTime;
+    public SummaryTable() {
+        
+    }
+    public SummaryTable(Label caseId, Label caseName,Label status,Label startTime, Label endTime) {
+        
+        this.testCaseId = caseId;
+        this.testCaseName = caseName;
+        this.testCaseStatus = status;
+        this.testCaseStartTime =startTime;
+        this.testCaseEndTime = endTime;
+    }
+    
+  
+     public Label getTestCaseId() {
+        return  testCaseId;
+    }
+    public void setTestCaseId(Label newCaseId) {
+        testCaseId = newCaseId;
+    }
+    public Label getTestCaseName() {
+        return  testCaseName;
+    }
+    public void setTestCaseName(Label newCaseName) {
+        testCaseName = newCaseName;
+    }
+    public Label getTestCaseStatus() {
+        return  testCaseStatus;
+    }
+    public void setTestCaseStatus(Label newCaseStatus) {
+        testCaseStatus = newCaseStatus;
+    }
+    
+    public Label getTestCaseStartTime() {
+        return  testCaseStartTime;
+    }
+    public void setTestCaseStartTime(Label newCaseStartTime) {
+        testCaseStartTime = newCaseStartTime;
+    }
+    public Label getTestCaseEndTime() {
+        return  testCaseEndTime;
+    }
+    public void setTestCaseEndTime(Label newCaseEndTime) {
+        testCaseEndTime = newCaseEndTime;
+    }
+   
+    
+}
diff --git a/TestON/TAI/src/tai_ofa/TAILocale.java b/TestON/TAI/src/tai_ofa/TAILocale.java
new file mode 100644
index 0000000..8f002f2
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/TAILocale.java
@@ -0,0 +1,160 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package tai_ofa;
+
+
+import java.text.MessageFormat;
+import java.util.*;
+
+/**
+ *
+ * @author Raghav Kashyap (raghavkashyap@paxterrasolutions.com)
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+ */
+public class TAILocale {
+    
+    String fileMenu, viewMenu, editMenu, helpMenu, runMenu,OFAHarnessPath,hierarchyTestON;
+    String New, newTestScript, newParams, newTopology,newDriver;
+    String open, save, saveAs, saveAll, close, closeAll, exit;
+    String copy, cut, paste, select, selectAll, pauseTest, resumeTest, stopTest,aboutHelp;
+    String driverExplorer, logExplorer, ProjectExplorer;
+    String contextNew, contextTest, contextTpl, contextParam, contextOpen, contextCut, contextCopy, contextPaste, contextDelete, contextRefresh;
+    String wizTitle, wiz_Previous, wizN_ext, wizCancel, wiz_Finish, wizTestName, wizTestParams, wizEmailId, wizNumberofTestCases, wizEstimatedTime, wizProject, wizParamName, wizTopologyName;
+    String wizProjectWizardId, wizTestWizardId, wizTopologyWizardId;
+    String topoTitle, topoProperties, topoInterfaces, topoAttribute, topoValue, topoHost, topoUserName, topoPassword, topoTransport;
+    String topoSSH, topoTELNET, topoFTP, topoRLOGIN, topoPrompt, topoSave, topoDefault, topoCancel, topoAttribue, topoValues;
+    String testSummaryEndTest, testSummaryTestSummary, testSummaryEnterComment, testSummaryConsoleOutput, summary, information;
+    String testSummaryViewLog, testSummaryExecutionStatus, testSummaryTestCaseId, testSummaryTestCaseName, testSummaryTestCaseTitle, testSummaryStartTest;
+    String testParameterTestDirctory, testParameteremailId, testParameterSelectTestCase, testParameterStartTest, testParameterCancel;
+    
+    public TAILocale(Locale currentLocale){
+        TAIProperties resource = new TAIProperties();
+        MessageFormat messageFormat = new MessageFormat("");
+        messageFormat.setLocale(currentLocale);
+        
+        hierarchyTestON = (String) resource.handleObject("hierarchyTestON");
+        OFAHarnessPath =  (String) resource.handleObject("OFAHarnessPath");
+        fileMenu = (String) resource.handleObject("File");
+        viewMenu = (String) resource.handleObject("View");
+        editMenu = (String) resource.handleObject("Edit");
+        helpMenu= (String) resource.handleObject("Help");
+        runMenu = (String) resource.handleObject("Run");
+        pauseTest = (String) resource.handleObject("Pause");
+        resumeTest = (String) resource.handleObject("Resume");
+        stopTest = (String) resource.handleObject("Stop");
+        aboutHelp = (String) resource.handleObject("About");
+        driverExplorer = (String) resource.handleObject("DriverExplorer");
+        logExplorer= (String) resource.handleObject("LogExplorer");
+        ProjectExplorer = (String) resource.handleObject("ProjectExplorer");
+        copy = (String) resource.handleObject("Copy");
+        cut = (String) resource.handleObject("Cut");
+        paste = (String) resource.handleObject("Paste");
+        select = (String) resource.handleObject("Select");
+        selectAll = (String) resource.handleObject("Select All");
+        New =  (String) resource.handleObject("New");
+        open = (String) resource.handleObject("Open");
+        save = (String) resource.handleObject("Save");
+        saveAs = (String) resource.handleObject("SaveAs");
+        saveAll = (String) resource.handleObject("Save All");
+        close = (String) resource.handleObject("Close");
+        closeAll = (String) resource.handleObject("CloseAll");
+        exit = (String) resource.handleObject("Exit");
+        newDriver = (String) resource.handleObject("Driver");
+        newTestScript = (String) resource.handleObject("newTestScript");
+        newParams = (String) resource.handleObject("Params");
+        newTopology = (String) resource.handleObject("Topology");
+        
+        // project explorer context menu
+
+        contextNew = (String) resource.handleObject("New");
+        contextTest = (String) resource.handleObject("Test");
+
+        contextParam = (String) resource.handleObject("Params");
+        contextTpl = (String) resource.handleObject("Tpl");
+
+        contextOpen = (String) resource.handleObject("Open");
+        contextCut = (String) resource.handleObject("Cut");
+
+        contextCopy = (String) resource.handleObject("Copy");;
+        contextPaste = (String) resource.handleObject("Paste");
+
+        contextRefresh = (String) resource.handleObject("Refresh");
+        contextDelete = (String) resource.handleObject("Delete");
+        
+        //OFA Wizards
+        wizTitle = (String) resource.handleObject("wizTitle");
+        wiz_Previous = (String) resource.handleObject("wiz_Previous");
+        wizN_ext = (String) resource.handleObject("wizN_ext");
+        wizCancel = (String) resource.handleObject("wizCancel");
+        wiz_Finish = (String) resource.handleObject("wiz_Finish");
+
+        wizTestName = (String) resource.handleObject("wizTestName");
+        wizTestParams = (String) resource.handleObject("wizTestParams");
+        wizEmailId = (String) resource.handleObject("wizEmailId");
+        wizNumberofTestCases = (String) resource.handleObject("wizNumberofTestCases");
+        wizEstimatedTime = (String) resource.handleObject("wizEstimatedTime");
+        wizProject = (String) resource.handleObject("wizProject");
+        wizParamName = (String) resource.handleObject("wizParamName");
+        wizTopologyName = (String) resource.handleObject("wizTopologyName");
+
+
+        wizProjectWizardId = (String) resource.handleObject("wizProjectWizardId");
+        wizTestWizardId = (String) resource.handleObject("wizTestWizardId");
+        wizTopologyWizardId = (String) resource.handleObject("wizTopologyWizardId");
+
+        // OFA Topology 
+
+        topoTitle = (String) resource.handleObject("topoTitle");
+        topoProperties = (String) resource.handleObject("topoProperties");
+        topoInterfaces = (String) resource.handleObject("topoInterfaces");
+        topoAttribute = (String) resource.handleObject("topoAttribute");
+        topoValue = (String) resource.handleObject("topoValue");
+        topoHost = (String) resource.handleObject("topoHost");
+        topoUserName = (String) resource.handleObject("topoUserName");
+        topoPassword = (String) resource.handleObject("topoPassword");
+        topoTransport = (String) resource.handleObject("topoTransport");
+        topoSSH = (String) resource.handleObject("topoSSH");
+        topoTELNET = (String) resource.handleObject("topoTELNET");
+        topoFTP = (String) resource.handleObject("topoFTP");
+        topoRLOGIN = (String) resource.handleObject("topoRLOGIN");
+        topoPrompt = (String) resource.handleObject("topoPrompt");
+        topoSave = (String) resource.handleObject("topoSave");
+        topoDefault = (String) resource.handleObject("topoDefault");
+        topoCancel = (String) resource.handleObject("topoCancel");
+        topoValues = (String) resource.handleObject("topoValues");
+        
+        // OFA Test Summary
+
+        testSummaryViewLog = (String) resource.handleObject("testSummaryViewLog");
+        testSummaryTestCaseTitle = (String) resource.handleObject("testSummaryExecutionStatus");
+        testSummaryTestCaseId = (String) resource.handleObject("testSummaryTestCaseId");
+        testSummaryTestCaseName = (String) resource.handleObject("testSummaryTestCaseName");
+        testSummaryExecutionStatus = (String) resource.handleObject("testSummaryTestCaseStatus");
+        testSummaryStartTest = (String) resource.handleObject("testSummaryStartTest");
+        testSummaryEndTest = (String) resource.handleObject("testSummaryEndTest");
+        testSummaryTestSummary = (String) resource.handleObject("testSummaryTestSummary");
+        summary = (String) resource.handleObject("summary");
+        information = (String) resource.handleObject("information");
+        testSummaryEnterComment = (String) resource.handleObject("testSummaryEnterComment");
+        testSummaryConsoleOutput = (String) resource.handleObject("testSummaryConsoleOutput");
+        testParameterCancel = (String) resource.handleObject("testParameterCancel");
+
+        
+        
+    }
+}
diff --git a/TestON/TAI/src/tai_ofa/TAIProperties.java b/TestON/TAI/src/tai_ofa/TAIProperties.java
new file mode 100644
index 0000000..8810c8b
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/TAIProperties.java
@@ -0,0 +1,386 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package tai_ofa;
+import java.util.*;
+
+/**
+ *
+ * @author Raghav Kashyap (raghavkashyap@paxterrasolutions.com)
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+ */
+public class TAIProperties extends ResourceBundle {
+    
+    public Object handleObject(String key){
+      //Set TestON Hierarchy path here
+        if (key.equals("hierarchyTestON")){
+            return "/home/paxterra/Desktop/TestON/";
+        }
+        
+        
+       if (key.equals("OFAHarnessPath")){
+            return "/home/paxterra/Music/TAI_OFA/src/";
+        }    
+                
+        if (key.equals("File")){
+            return "File";
+        }
+        
+        if (key.equals("View")) {
+            return "View";
+        }
+        
+        if (key.equals("Run")){
+            return "Run";
+        }
+        
+        if (key.equals("Edit")){
+            return "Edit";
+        }
+        
+        if (key.equals("Help")){
+            return "Help";
+        }
+        
+        if (key.equals("New")){
+            return "New";
+        }
+        
+        if (key.equals("Open")){
+            return "Open";
+        }
+        
+        if(key.equals("Pause")) {
+            return "Pause";
+        }
+        if(key.equals("Resume")) {
+            return "Resume";
+        }
+        if(key.equals("Stop")) {
+            return "Stop";
+        }
+        if(key.equals("About")) {
+            return "About";
+        }
+        
+        if(key.equals("DriverExplorer")) {
+            return "Driver Explorer";
+        }
+        
+        if(key.equals("ProjectExplorer")) {
+            return "Project Explorer";
+        }
+        
+        if(key.equals("LogExplorer")) {
+            return "Log Explorer";
+        }
+        
+        if(key.equals("Cut")) {
+            return "Cut";
+        }
+        if(key.equals("Copy")) {
+            return "Copy";
+        }
+        
+        if(key.equals("Paste")) {
+            return "Paste";
+        }
+        
+        if(key.equals("Select")) {
+            return "Select";
+        }
+        if(key.equals("Select All")) {
+            return "Select All";
+        }
+        if(key.equals("Save")) {
+            return "Save";
+        }
+        if(key.equals("SaveAs")) {
+            return "Save As";
+        }
+        
+        if(key.equals("Save All")) {
+            return "SaveAll";
+        }
+        
+        if(key.equals("Close")) {
+            return "Close";
+        }
+        if(key.equals("CloseAll")) {
+            return "CloseAll";
+        }
+        if(key.equals("Exit")) {
+            return "Exit";
+        }
+        
+        if(key.equals("Exit")) {
+            return "Exit";
+        }
+        
+        if(key.equals("Driver")) {
+            return "Component Driver";
+        }
+        if(key.equals("Params")) {
+            return "Params";
+        }
+        if(key.equals("Topology")) {
+            return "Topology";
+        }
+        if(key.equals("newTestScript")) {
+            return "Test Script";
+        }
+        
+        //Context Menu
+         if (key.equals("New")) {
+            return "New";
+        }
+
+        if (key.equals("Test")) {
+            return "Test";
+        }
+        if (key.equals("Param")) {
+            return "Params";
+        }
+        if (key.equals("Tpl")) {
+            return "TPL";
+        }
+
+        if (key.equals("Open")) {
+            return "Open";
+        }
+
+        if (key.equals("Cut")) {
+            return "Cut";
+        }
+
+        if (key.equals("Copy")) {
+            return "Copy";
+        }
+
+        if (key.equals("Paste")) {
+            return "Paste";
+        }
+        if (key.equals("Refresh")) {
+            return "Refresh";
+        }
+
+        if (key.equals("Delete")) {
+            return "Delete";
+        }
+        
+        //OFA WIZARDS
+        if (key.equals("wizTitle")) {
+            return "AutoMate";
+        }
+        if (key.equals("wiz_Previous")) {
+            return "_Previous";
+        }
+
+        if (key.equals("wizN_ext")) {
+            return "N_ext";
+        }
+        if (key.equals("wizCancel")) {
+            return "Cancel";
+        }
+
+        if (key.equals("wiz_Finish")) {
+            return "_Finish";
+        }
+        if (key.equals("wizTestName")) {
+            return "Test Name";
+        }
+
+        if (key.equals("wizTestParams")) {
+            return "TEST PARAMS:";
+        }
+        if (key.equals("wizEmailId")) {
+            return "Email Id";
+        }
+
+        if (key.equals("wizNumberofTestCases")) {
+            return "Number of TestCases";
+        }
+        if (key.equals("wizEstimatedTime")) {
+            return "Estimated Time";
+        }
+
+        if (key.equals("wizProject")) {
+            return "Project";
+        }
+        if (key.equals("wizParamName")) {
+            return "Param Name";
+        }
+
+        if (key.equals("wizTopologyName")) {
+            return "Topology Name";
+        }
+        if (key.equals("wizProjectWizardId")) {
+            return "projectWizard";
+        }
+
+        if (key.equals("wizTestWizardId")) {
+            return "testWizard";
+        }
+        if (key.equals("wizTopologyWizardId")) {
+            return "topologyWizard";
+        }
+
+        if (key.equals("wiz")) {
+            return "Attribue";
+        }
+        if (key.equals("wiz")) {
+            return "Values";
+        }
+            
+        // OFA Topology
+
+        if (key.equals("topoTitle")) {
+            return "Topology";
+        }
+        if (key.equals("topoProperties")) {
+            return "Properties";
+        }
+
+        if (key.equals("topoInterfaces")) {
+            return "Interfaces";
+        }
+        if (key.equals("topoAttribute")) {
+            return "Attribute";
+        }
+
+        if (key.equals("topoValue")) {
+            return "Value";
+        }
+
+        if (key.equals("topoHost")) {
+            return "Host";
+        }
+        if (key.equals("topoUserName")) {
+            return "User Name";
+        }
+        if (key.equals("topoPassword")) {
+            return "Password";
+        }
+        if (key.equals("topoTransport")) {
+            return "Transport";
+        }
+
+        if (key.equals("topoSSH")) {
+            return "SSH";
+        }
+
+        if (key.equals("topoTELNET")) {
+            return "TELNET";
+        }
+        if (key.equals("topoFTP")) {
+            return "FTP";
+        }
+        if (key.equals("topoRLOGIN")) {
+            return "RLOGIN";
+        }
+
+
+
+        if (key.equals("topoPrompt")) {
+            return "Prompt";
+        }
+
+        if (key.equals("topoSave")) {
+            return "Save";
+        }
+        if (key.equals("topoDefault")) {
+            return "Default";
+        }
+        if (key.equals("topoCancel")) {
+            return "Cancel";
+        }
+
+
+        if (key.equals("topoInterfaces")) {
+            return "Interfaces";
+        }
+        if (key.equals("topoAttribue")) {
+            return "Attribue";
+        }
+        if (key.equals("topoValues")) {
+            return "Values";
+        }
+
+
+
+
+             
+        // OFA TestSummary
+
+
+        if (key.equals("testSummaryViewLog")) {
+            return "View Logs";
+        }
+        if (key.equals("testSummaryExecutionStatus")) {
+            return "Execution Status";
+        }
+
+        if (key.equals("testSummaryTestCaseId")) {
+            return "ID";
+        }
+        if (key.equals("testSummaryTestCaseName")) {
+            return "Name";
+        }
+
+        if (key.equals("testSummaryTestCaseStatus")) {
+            return "Status";
+        }
+
+        if (key.equals("testSummaryStartTest")) {
+            return "Start Test";
+        }
+        if (key.equals("testSummaryEndTest")) {
+            return "End Test";
+        }
+        if (key.equals("summary")) {
+            return "Summary";
+        }
+        if (key.equals("information")) {
+            return "Information";
+        }
+
+        if (key.equals("testSummaryTestSummary")) {
+            return "Test Summary";
+        }
+
+        if (key.equals("testSummaryEnterComment")) {
+            return "Test Summary Console";
+        }
+        if (key.equals("testSummaryConsoleOutput")) {
+            return "Console output";
+        }
+        
+     return null;     
+    }
+
+    @Override
+    protected Set<String> handleGetObject(String key) {
+        
+        return new HashSet<String>(Arrays.asList("okKey", "cancelKey"));
+    }
+
+    @Override
+    public Enumeration<String> getKeys() {
+        return Collections.enumeration(keySet());
+    }
+    
+}
diff --git a/TestON/TAI/src/tai_ofa/TAI_OFA.java b/TestON/TAI/src/tai_ofa/TAI_OFA.java
new file mode 100644
index 0000000..fc47b5b
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/TAI_OFA.java
@@ -0,0 +1,1326 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package tai_ofa;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javafx.application.Application;
+import javafx.application.Platform;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.ObservableList;
+import javafx.event.ActionEvent;
+import javafx.event.Event;
+import javafx.event.EventHandler;
+import javafx.geometry.Insets;
+import javafx.geometry.Orientation;
+import javafx.geometry.Pos;
+import javafx.scene.Group;
+import javafx.scene.Node;
+import javafx.scene.Scene;
+import javafx.scene.control.Accordion;
+import javafx.scene.control.Button;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.ComboBoxBuilder;
+import javafx.scene.control.ContextMenu;
+import javafx.scene.control.Label;
+import javafx.scene.control.Menu;
+import javafx.scene.control.MenuBar;
+import javafx.scene.control.MenuButton;
+import javafx.scene.control.MenuItem;
+import javafx.scene.control.Separator;
+import javafx.scene.control.SeparatorMenuItem;
+import javafx.scene.control.SplitPane;
+import javafx.scene.control.Tab;
+import javafx.scene.control.TabPane;
+import javafx.scene.control.TextArea;
+import javafx.scene.control.TextField;
+import javafx.scene.control.TextFieldBuilder;
+import javafx.scene.control.TitledPane;
+import javafx.scene.control.ToolBar;
+import javafx.scene.control.Tooltip;
+import javafx.scene.control.TreeCell;
+import javafx.scene.control.TreeItem;
+import javafx.scene.control.TreeView;
+import javafx.scene.effect.Effect;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.InputEvent;
+import javafx.scene.input.MouseButton;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Pane;
+import javafx.scene.layout.VBox;
+import javafx.scene.layout.VBoxBuilder;
+import javafx.scene.paint.Color;
+import javafx.scene.text.Font;
+import javafx.scene.text.FontWeight;
+import javafx.scene.text.Text;
+import javafx.stage.FileChooser;
+import javafx.stage.FileChooser.ExtensionFilter;
+import javafx.stage.Modality;
+import javafx.stage.Screen;
+import javafx.stage.Stage;
+import javafx.util.Callback;
+import javax.swing.JOptionPane;
+import javax.swing.SingleSelectionModel;
+
+/**
+ *
+ * @author Raghav Kashyap (raghavkashyap@paxterrasolutions.com)
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+ * 
+ */
+public class TAI_OFA extends Application {
+
+    MenuBar OFA_MenuBar = new MenuBar();
+    Scene scene;
+    TAILocale label = new TAILocale(new Locale("en", "EN"));
+    Stage copyStage;
+    double toolBarHeight, menuBarHeight;
+    ToolBar toolbar = new ToolBar();
+    TitledPane projectExplorer;
+    TitledPane logExlorer;
+    TitledPane driverExplorer;
+    TreeView<String> projectExplorerTreeView, logExplorerTreeView, driverExplorerTreeView;
+    TreeItem<String> driverExplorerTree;
+    static double OFAContainerWidth, OFAContainerHeight;
+    boolean projectExplorerFlag, editorFlag;
+    ContextMenu contextMenu;
+    TAI_OFA OFAReference;
+    TabPane explorerTabPane, editorTabPane;
+    FileChooser openParams;
+    OFAFileOperations fileOperation = new OFAFileOperations();
+    Tab explorerTab;
+    Accordion explorer;
+    TreeItem<String> projectExplorerTree, logExplorerTree;
+    OFAWizard wizard;
+    AddParams addParams;
+    String paramsFileContent, projectWorkSpacePath;
+    OFATestSummary testSummaryPop;
+    Button Save;
+    MenuItem saveAll;
+    MenuItem closeAll;
+
+    public TAI_OFA() {
+        OFAReference = this;
+
+    }
+
+    public TAI_OFA(TabPane pane, Scene sc, TabPane pane1) {
+        editorTabPane = pane;
+        scene = sc;
+        explorerTabPane = pane1;
+        OFAReference = this;
+    }
+
+    @Override
+    public void start(Stage primaryStage) {
+        copyStage = primaryStage;
+        Group root = new Group();
+
+        projectWorkSpacePath = label.hierarchyTestON;
+        scene = new Scene(root, 800, 600, Color.DARKGRAY);
+        VBox baseBox = new VBox();
+        getFileMenu();
+        getEditMenu();
+        getViewMenu();
+        getRunMenu();
+        getHelpMenu();
+        getToolBar();
+        OFA_MenuBar.setPrefWidth(scene.widthProperty().get());
+        toolbar.prefWidthProperty().bind(scene.widthProperty());
+        toolbar.setMinHeight(scene.heightProperty().get() / 20);;
+        toolBarHeight = toolbar.getMinHeight();
+        OFA_MenuBar.setPrefHeight(scene.heightProperty().get() / 20);
+        menuBarHeight = OFA_MenuBar.getPrefHeight();
+        explorerTabPane = new TabPane();
+        editorTabPane = new TabPane();
+        explorer = new Accordion();
+        explorerTab = new Tab("Explorer");
+        explorerTabPane.setLayoutX(0);
+        projectExplorerFlag = true;
+
+        getProjectExplorer();
+        getLogExplorer();
+        getDriverExplorer();
+        explorer.setMinSize(200, scene.getHeight() - 40);
+        explorer.getPanes().addAll(projectExplorer, logExlorer, driverExplorer);
+        explorerTabPane.prefHeightProperty().bind(scene.heightProperty());
+        explorerTabPane.setMinWidth(200);
+        explorerTab.setContent(explorer);
+        explorerTabPane.getTabs().addAll(explorerTab);
+        editorTabPane.setLayoutX(270);
+        final Pane basePane = new Pane();
+        explorerTabPane.prefHeightProperty().bind(scene.heightProperty().subtract(toolBarHeight + menuBarHeight + 1));
+        basePane.getChildren().addAll(explorerTabPane, new Separator(Orientation.VERTICAL), editorTabPane);
+        basePane.autosize();
+        baseBox.getChildren().addAll(OFA_MenuBar, toolbar, basePane);
+        baseBox.prefHeightProperty().bind(primaryStage.heightProperty());
+        OFAContainerWidth = scene.getWidth();
+        OFAContainerHeight = scene.getHeight();
+        root.getChildren().addAll(baseBox);
+        primaryStage.setTitle("TestON - Automation is O{pe}N");
+        primaryStage.setScene(scene);
+        primaryStage.setResizable(true);
+        primaryStage.sizeToScene();
+        primaryStage.show();
+    }
+
+    public void getFileMenu() {
+
+
+        //adding Menus 
+        Menu fileMenu = new Menu(label.fileMenu);
+
+        //adding File Menu
+        Image newImage = new Image("images/newIcon.jpg", 20.0, 20.0, true, true);
+        Image saveAllImage = new Image("images/saveAll.jpg", 20.0, 20.0, true, true);
+
+        Menu newFileMenu = new Menu("New", new ImageView(newImage));
+        MenuItem newTest = new MenuItem("New Test");
+        MenuItem componentDriver = new MenuItem(label.newDriver);
+        MenuItem newParams = new MenuItem(label.newParams);
+        MenuItem newTopology = new MenuItem(label.newTopology);
+        MenuItem testScript = new MenuItem(label.newTestScript);
+        newFileMenu.getItems().addAll(newTest, componentDriver, newParams, newTopology, testScript);
+
+
+        newTopology.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                try {
+                    wizard = new OFAWizard(projectExplorerTree, 3, projectExplorerTree.getChildren(), projectExplorerTreeView);
+                    wizard.setOFA(OFAReference);
+                    wizard.start(new Stage());
+
+                } catch (Exception ex) {
+                    Logger.getLogger(TAI_OFA.class.getName()).log(Level.SEVERE, null, ex);
+                }
+            }
+        });
+
+        newTest.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                wizard = new OFAWizard(projectExplorerTree, 1, projectExplorerTree.getChildren(), projectExplorerTreeView);
+                wizard.setOFA(OFAReference);
+                try {
+                    wizard.start(new Stage());
+                } catch (Exception ex) {
+                    Logger.getLogger(TAI_OFA.class.getName()).log(Level.SEVERE, null, ex);
+                }
+            }
+        });
+
+        newParams.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                addParams = new AddParams();
+                addParams.setOFA(OFAReference);
+                addParams.getNewParams();
+            }
+        });
+
+
+        Image openImage = new Image("images/open.png", 15.0, 15.0, true, true);
+        Menu open = new Menu(label.open, new ImageView(openImage));
+        MenuItem openParams = new MenuItem("Params");
+        Menu openTestScript = new Menu("Test Script");
+        MenuItem pyTest = new MenuItem("Python TestScript");
+        MenuItem ospkTest = new MenuItem("OpenSpeak TestScript");
+        openTestScript.getItems().addAll(pyTest, ospkTest);
+
+        MenuItem openTopology = new MenuItem("Topology");
+        MenuItem openDriver = new MenuItem("Driver");
+
+        open.getItems().addAll(openParams, openTopology, openTestScript, openDriver);
+
+        openParams.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                openFile("params", "");
+            }
+        });
+
+        ospkTest.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                openFile("ospk", "");
+            }
+        });
+
+
+        Image saveImage = new Image("images/Save_24x24.png", 15.0, 15.0, true, true);
+        MenuItem save = new MenuItem(label.save, new ImageView(saveImage));
+
+        MenuItem saveAs = new MenuItem(label.saveAs);
+        saveAll = new MenuItem(label.saveAll, new ImageView(saveAllImage));
+
+        Image exitImage = new Image("images/exit.gif", 15.0, 15.0, true, true);
+        MenuItem exit = new MenuItem(label.exit, new ImageView(exitImage));
+        exit.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                copyStage.close();
+            }
+        });
+        Image closeImage = new Image("images/close_icon2.jpg", 15.0, 15.0, true, true);
+        MenuItem close = new MenuItem(label.close, new ImageView(closeImage));
+        closeAll = new MenuItem(label.closeAll);
+        fileMenu.getItems().addAll(newFileMenu, open, save, saveAll, saveAs, new SeparatorMenuItem(), close, closeAll, new SeparatorMenuItem(), exit);
+
+        OFA_MenuBar.getMenus().addAll(fileMenu);
+    }
+
+    public void getProjectExplorer() {
+
+        projectWorkSpacePath = label.hierarchyTestON + "/tests/";
+        File[] file = File.listRoots();
+        Path name = new File(projectWorkSpacePath).toPath();
+        OFALoadTree treeNode = new OFALoadTree(name);
+
+        treeNode.setExpanded(true);
+        projectExplorerTree = treeNode;
+        for (int i = 0; i < treeNode.getChildren().size(); i++) {
+            if (treeNode.getChildren().get(i).getValue().equals("__init__")) {
+                treeNode.getChildren().remove(treeNode.getChildren().get(i));
+            }
+        }
+        projectExplorerTreeView = new TreeView<String>(treeNode);
+        VBox projectExpl = new VBox();
+        Button newTest = new Button("New Test");
+        projectExplorerTreeView.setMinHeight(scene.getHeight() - (40 + toolBarHeight + menuBarHeight));
+        projectExpl.getChildren().addAll(newTest, projectExplorerTreeView);
+        projectExplorer = new TitledPane("Project Explorer", projectExpl);
+        projectExplorer.setContent(projectExpl);
+
+        newTest.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                wizard = new OFAWizard(projectExplorerTree, 1, projectExplorerTree.getChildren(), projectExplorerTreeView);
+                wizard.setOFA(OFAReference);
+                try {
+                    wizard.start(new Stage());
+                } catch (Exception ex) {
+                    Logger.getLogger(TAI_OFA.class.getName()).log(Level.SEVERE, null, ex);
+                }
+            }
+        });
+
+        projectExplorerTreeView.setOnMouseClicked(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent arg0) {
+
+                if (arg0.getButton() == MouseButton.SECONDARY) {
+                    contextMenu();
+                    contextMenu.show(projectExplorerTreeView, arg0.getScreenX(), arg0.getScreenY());
+
+                } else if (arg0.getClickCount() == 2) {
+                    String path = "";
+                    TreeItem<String> selectedTreeItem = projectExplorerTreeView.getSelectionModel().getSelectedItem();
+                    try {
+
+                        path = label.hierarchyTestON + "/tests/" + selectedTreeItem.getParent().getValue().toString() + "/" + selectedTreeItem.getValue();
+                        if (selectedTreeItem.isLeaf()) {
+                            if (selectedTreeItem.getGraphic().getId().equals(".params")) {
+                                path = path + ".params";
+                            } else if (selectedTreeItem.getGraphic().getId().equals(".topo")) {
+                                path = path + ".topo";
+                            } else if (selectedTreeItem.getGraphic().getId().equals(".py")) {
+                                path = path + ".py";
+                            } else if (selectedTreeItem.getGraphic().getId().equals(".ospk")) {
+                                path = path + ".ospk";
+                            }
+                            String fileContent = fileOperation.getContents(new File(path));
+                            editorFlag = true;
+                            checkEditor();
+                            OFATabEditor(new CodeEditor(fileContent), new CodeEditorParams(fileContent), new File(path).getAbsolutePath(), "");
+                        } else if (!selectedTreeItem.isLeaf()) {
+                        }
+
+
+
+                    } catch (Exception e) {
+                    }
+                }
+            }
+        });
+
+        projectExplorerTreeView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() {
+            @Override
+            public void changed(ObservableValue observable, Object oldValus, Object newValue) {
+                ObservableList<TreeItem<String>> tata = projectExplorerTreeView.getSelectionModel().getSelectedItems();
+
+                TreeItem treeItem = (TreeItem) newValue;
+            }
+        });
+
+
+        explorerTab.setOnClosed(new EventHandler<Event>() {
+            @Override
+            public void handle(Event closeEvent) {
+                explorerTabPane.setVisible(false);
+                projectExplorerFlag = false;
+                checkEditor();
+
+            }
+        });
+
+
+    }
+
+    public void loadLogExlporer() {
+        String projectWorkSpacePaths = label.hierarchyTestON + "/logs/";
+        File[] file = File.listRoots();
+        Path name = new File(projectWorkSpacePaths).toPath();
+        OFALoadTree treeNode = new OFALoadTree(name);
+        treeNode.setExpanded(true);
+        logExplorerTreeView = new TreeView<String>(treeNode);
+    }
+
+    public void getLogExplorer() {
+
+        loadLogExlporer();
+        VBox logExpl = new VBox();
+        logExplorerTreeView.setMinHeight(scene.getHeight() - (toolBarHeight + menuBarHeight + 20));
+        logExpl.getChildren().addAll(logExplorerTreeView);
+        logExlorer = new TitledPane("Log Explorer", logExpl);
+
+        VBox logExplore = new VBox();
+        Button refresh = new Button("refresh");
+        logExplorerTreeView.setMinHeight(scene.getHeight() - (40 + toolBarHeight + menuBarHeight));
+        logExplore.getChildren().addAll(refresh, logExplorerTreeView);
+        logExlorer.setContent(logExplore);
+
+        refresh.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                String projectWorkSpacePaths = label.hierarchyTestON + "/logs/";
+                File[] file = File.listRoots();
+                Path name = new File(projectWorkSpacePaths).toPath();
+                OFALoadTree treeNode = new OFALoadTree(name);
+                treeNode.setExpanded(true);
+
+                logExplorerTreeView.setRoot(treeNode);
+            }
+        });
+
+
+        logExplorerTreeView.setOnMouseClicked(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent click) {
+                if (click.getClickCount() == 2 && click.getButton() == MouseButton.PRIMARY) {
+                    TreeItem<String> selectedItem = logExplorerTreeView.getSelectionModel().getSelectedItem();
+                    String fileExtentsion = selectedItem.getGraphic().getId();
+                    String selectedFilePath = label.hierarchyTestON + "/logs/" + selectedItem.getParent().getValue() + "/" + selectedItem.getValue() + fileExtentsion;
+                    String fileContent = fileOperation.getContents(new File(selectedFilePath));
+                    editorFlag = true;
+
+                    checkEditor();
+                    OFATabEditor(new CodeEditor(fileContent), new CodeEditorParams(""), new File(selectedFilePath).getAbsolutePath(), "");
+                }
+            }
+        });
+    }
+
+    public void getDriverExplorer() {
+
+        projectWorkSpacePath = label.hierarchyTestON + "/drivers/common";
+
+        final Node rootIcon = new ImageView(new Image(getClass().getResourceAsStream("/images/project.jpeg"), 16, 16, true, true));
+        driverExplorerTree = new TreeItem<String>("Drivers");
+        File[] file = File.listRoots();
+
+        Path name = new File(projectWorkSpacePath).toPath();
+        OFALoadTree treeNode = new OFALoadTree(name);
+
+        driverExplorerTree.setExpanded(true);
+        //create the tree view
+        driverExplorerTreeView = new TreeView<String>(treeNode);
+        driverExplorer = new TitledPane("Driver Explorer", driverExplorerTreeView);
+
+        driverExplorer.prefHeight(scene.heightProperty().get());
+
+        VBox driverExpl = new VBox();
+        driverExpl.getChildren().addAll(new Button("New Driver"), driverExplorerTreeView);
+        driverExplorerTreeView.setShowRoot(false);
+        driverExplorerTreeView.setMinHeight(scene.getHeight() - (toolBarHeight + menuBarHeight + 50));
+
+        driverExplorer.setContent(driverExpl);
+        driverExplorer.prefHeight(scene.heightProperty().get());
+
+
+        ObservableList<TreeItem<String>> children = driverExplorerTree.getChildren();
+        Iterator<TreeItem<String>> tree = children.iterator();
+        while (tree.hasNext()) {
+            TreeItem<String> value = tree.next();
+            if (value.getValue().equals("common")) {
+                driverExplorerTreeView.setShowRoot(false);
+            }
+        }
+
+        driverExplorerTreeView.setOnMouseClicked(new EventHandler<MouseEvent>() {
+            @Override
+            public void handle(MouseEvent event) {
+
+                if (event.getClickCount() == 1 && event.getButton() == MouseButton.PRIMARY) {
+                    //final Node rootIcon = new ImageView(new Image(getClass().getResourceAsStream("/images/project.jpeg")));
+                    TreeItem<String> driverSelectedItem = driverExplorerTreeView.getSelectionModel().getSelectedItem();
+
+                    try {
+                        String[] splitSelectedDriver = driverSelectedItem.getValue().split("\\.");
+
+                        String path = null;
+                        TreeItem selectedTreeItem = driverSelectedItem.getParent();
+                        TreeItem selectedParentItem = selectedTreeItem.getParent();
+
+                        path = projectWorkSpacePath + "/" + driverSelectedItem.getParent().getParent().getValue() + "/" + driverSelectedItem.getParent().getValue()
+                                + "/" + driverSelectedItem.getValue() + ".py";
+
+                        if (driverSelectedItem.getParent().getValue().equals("emulator")) {
+                            path = projectWorkSpacePath + "/" + driverSelectedItem.getParent().getParent().getValue() + "/" + driverSelectedItem.getParent().getValue()
+                                    + "/" + driverSelectedItem.getValue() + ".py";
+                        } else if (driverSelectedItem.getParent().getValue().equals("api")) {
+                            path = projectWorkSpacePath + "/" + driverSelectedItem.getParent().getValue() + "/" + driverSelectedItem.getValue() + ".py";
+                        } else if (driverSelectedItem.getParent().getValue().equals("tool")) {
+                            path = projectWorkSpacePath + "/" + driverSelectedItem.getParent().getParent().getValue() + "/" + driverSelectedItem.getParent().getValue()
+                                    + "/" + driverSelectedItem.getValue() + ".py";
+                        } else if (driverSelectedItem.getParent().getValue().equals("cli")) {
+                            path = projectWorkSpacePath + "/" + driverSelectedItem.getParent().getValue() + "/" + driverSelectedItem.getValue() + ".py";
+                        }
+                        String fileContent = fileOperation.getContents(new File(path));
+                        projectExplorerFlag = true;
+                        checkEditor();
+                        OFATabEditor(new CodeEditor(fileContent), new CodeEditorParams(""), path, driverSelectedItem.getValue());
+
+
+                    } catch (Exception e) {
+                    }
+
+                }
+            }
+        });
+
+
+
+        driverExplorerTreeView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() {
+            @Override
+            public void changed(ObservableValue observable, Object oldValus, Object newValue) {
+                ObservableList<TreeItem<String>> tata = projectExplorerTreeView.getSelectionModel().getSelectedItems();
+
+                TreeItem treeItem = (TreeItem) newValue;
+            }
+        });
+
+        driverExplorerTree.setExpanded(true);
+
+    }
+
+    public void contextMenu() {
+        contextMenu = new ContextMenu();
+        Image copyImage = new Image("images/Copy.png", 20.0, 20.0, true, true);
+        Image cutImage = new Image("images/Cut.png", 20.0, 20.0, true, true);
+        Image pasteImage = new Image("images/Paste.jpg", 20.0, 20.0, true, true);
+        Image deleteImage = new Image("images/delete.png", 20.0, 20.0, true, true);
+
+        Menu newContextMenu = new Menu(label.contextNew);
+        MenuItem scriptContextMenu = new MenuItem(label.contextTest);
+        newContextMenu.getItems().add(scriptContextMenu);
+        MenuItem openContextMenu = new MenuItem(label.contextOpen);
+        MenuItem cutContextMenu = new MenuItem(label.contextCut, new ImageView(cutImage));
+        MenuItem copyContextMenu = new MenuItem(label.contextCopy, new ImageView(copyImage));
+        MenuItem pasteContextMenu = new MenuItem(label.contextPaste, new ImageView(pasteImage));
+        MenuItem refreshContextMenu = new MenuItem(label.contextRefresh);
+        MenuItem deleteContextMenu = new MenuItem(label.contextDelete, new ImageView(deleteImage));
+
+        refreshContextMenu.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                refreshLogExplorer();
+            }
+        });
+
+        openContextMenu.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent args0) {
+                TreeItem<String> selectedTreeItem = projectExplorerTreeView.getSelectionModel().getSelectedItem();
+
+            }
+        });
+
+        contextMenu.getItems().addAll(newContextMenu, openContextMenu, cutContextMenu, copyContextMenu, pasteContextMenu, refreshContextMenu, deleteContextMenu);
+        projectExplorerTreeView.contextMenuProperty().setValue(contextMenu);
+        scriptContextMenu.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent arg0) {
+            }
+        });
+    }
+
+    public void getEditMenu() {
+        //adding Edit Menu
+        Image copyImage = new Image("images/Copy.png", 20.0, 20.0, true, true);
+        Image cutImage = new Image("images/Cut.png", 20.0, 20.0, true, true);
+        Image pasteImage = new Image("images/Paste.jpg", 20.0, 20.0, true, true);
+
+
+        Menu editMenu = new Menu(label.editMenu);
+        MenuItem cut = new MenuItem(label.cut, new ImageView(cutImage));
+        MenuItem copy = new MenuItem(label.copy, new ImageView(copyImage));
+        MenuItem paste = new MenuItem(label.paste, new ImageView(pasteImage));
+        MenuItem select = new MenuItem(label.select);
+        MenuItem selectAll = new MenuItem(label.selectAll);
+
+        editMenu.getItems().addAll(cut, copy, paste, select, selectAll);
+        OFA_MenuBar.getMenus().addAll(editMenu);
+
+
+    }
+
+    public void getViewMenu() {
+        //add View Menu
+        Menu viewMenu = new Menu(label.viewMenu);
+        MenuItem Explorer = new MenuItem("Explorer");
+        MenuItem commandOptions = new MenuItem("CommandLine Explorer");
+
+
+        viewMenu.getItems().addAll(Explorer, commandOptions);
+        OFA_MenuBar.getMenus().addAll(viewMenu);
+
+        Explorer.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+
+                explorerTab = new Tab("Explorer");
+                explorerTabPane.setLayoutX(0);
+                projectExplorerFlag = true;
+
+                explorerTab.setContent(explorer);
+
+                explorerTabPane.getTabs().addAll(explorerTab);
+                editorTabPane.setLayoutX(270);
+                explorerTabPane.setVisible(true);
+                projectExplorerFlag = true;
+
+
+                checkEditor();
+
+
+            }
+        });
+
+
+    }
+
+    public void getToolBar() {
+        Image newImage = new Image("images/newIcon.jpg", 20.0, 20.0, true, true);
+        MenuButton New = new MenuButton("", new ImageView(newImage));
+        New.setTooltip(new Tooltip("New"));
+        MenuItem newTest = new MenuItem("New Test");
+        MenuItem componentDriver = new MenuItem(label.newDriver);
+        MenuItem newParams = new MenuItem(label.newParams);
+        MenuItem newTopology = new MenuItem(label.newTopology);
+        MenuItem testScript = new MenuItem(label.newTestScript);
+
+        New.getItems().addAll(newTest, componentDriver, newParams, newTopology, testScript);
+        New.setMinWidth(2);
+
+        newTest.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                wizard = new OFAWizard(projectExplorerTree, 1, projectExplorerTree.getChildren(), projectExplorerTreeView);
+                wizard.setOFA(OFAReference);
+                try {
+                    wizard.start(new Stage());
+                } catch (Exception ex) {
+                    Logger.getLogger(TAI_OFA.class.getName()).log(Level.SEVERE, null, ex);
+                }
+            }
+        });
+
+
+        newParams.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent arg0) {
+                try {
+                    wizard = new OFAWizard(projectExplorerTree, 2, projectExplorerTree.getChildren(), projectExplorerTreeView);
+                    wizard.setOFA(OFAReference);
+                    wizard.start(new Stage());
+
+                } catch (Exception ex) {
+                    Logger.getLogger(TAI_OFA.class.getName()).log(Level.SEVERE, null, ex);
+                }
+            }
+        });
+
+        //Open Icon on Tool Bar
+        Image openImage = new Image("images/open.png", 20.0, 20.0, true, true);
+        MenuButton Open = new MenuButton("", new ImageView(openImage));
+        Open.setTooltip(new Tooltip("Open"));
+        MenuItem openComponentDriver = new MenuItem(label.newDriver);
+        MenuItem openParams = new MenuItem(label.newParams);
+        MenuItem openTopology = new MenuItem(label.newTopology);
+        MenuItem openTestScript = new MenuItem(label.newTestScript);
+
+        Open.getItems().addAll(openComponentDriver, openParams, openTopology, openTestScript);
+        Image saveImage = new Image("images/Save_24x24.png", 20.0, 20.0, true, true);
+        Save = new Button("", new ImageView(saveImage));
+        Save.setTooltip(new Tooltip("Save"));
+
+        Image configImage = new Image("images/project_1.jpeg", 20.0, 20.0, true, true);
+        Button configuration = new Button("", new ImageView(configImage));
+        configuration.setTooltip(new Tooltip("Run With ..."));
+
+        Image playImage = new Image("images/Play.png", 20.0, 20.0, true, true);
+        MenuButton play = new MenuButton("", new ImageView(playImage));
+        play.setTooltip(new Tooltip("Run"));
+
+        MenuItem run = new MenuItem("Run");
+        MenuItem runWithOptionButton = new MenuItem("Run With ...");
+
+        play.getItems().addAll(run, runWithOptionButton);
+        Image pauseImage = new Image("images/Pause.png", 20.0, 20.0, true, true);
+        Button pause = new Button("", new ImageView(pauseImage));
+        pause.setTooltip(new Tooltip("Pause"));
+
+        run.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                testSummaryPop = new OFATestSummary(OFAReference, copyStage);
+                testSummaryPop.start(new Stage());
+                Runnable firstRunnable = new Runnable() {
+                    @Override
+                    public void run() {
+                        try {
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        }
+                    }
+                };
+                Runnable secondRunnable = new Runnable() {
+                    @Override
+                    public void run() {
+                        try {
+                            ExecuteTest testExecute = new ExecuteTest(testSummaryPop.getTable(), testSummaryPop.getData(), testSummaryPop.getChart(),
+                                    testSummaryPop.getFinalSummaryTable(), testSummaryPop.getFinalSummaryData(),
+                                    testSummaryPop.getVieLogsButton(), testSummaryPop.getpieChartData(),
+                                    testSummaryPop.getPassData(), testSummaryPop.getFailData(), testSummaryPop.getAbortData(),
+                                    testSummaryPop.getNoResultData(), editorTabPane.getSelectionModel().getSelectedItem().getText().substring(0, editorTabPane.getSelectionModel().getSelectedItem().getText().lastIndexOf('.')), testSummaryPop.getTextArea("log"), testSummaryPop.getStepTable(), testSummaryPop.getStepData(), testSummaryPop.getTextArea("pox"), testSummaryPop.getTextArea("mininet"), testSummaryPop.getTextArea("flowvisor"));
+
+                            testExecute.runTest();
+                        } catch (Exception iex) {
+                        }
+                    }
+                };
+
+                Platform.runLater(firstRunnable);
+                Platform.runLater(secondRunnable);
+            }
+        });
+
+
+        runWithOptionButton.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent t) {
+                OFATestParameters testParameter = new OFATestParameters(OFAReference);
+                testParameter.setProjectView(projectExplorerTreeView);
+                testParameter.setProjectList(projectExplorerTree.getChildren());
+                testParameter.start(new Stage());
+            }
+        });
+
+        Image stopImage = new Image("images/Stop.png", 20.0, 20.0, true, true);
+        Button stop = new Button("", new ImageView(stopImage));
+        stop.setTooltip(new Tooltip("Stop"));
+
+        Image resumeImage = new Image("images/Resume_1.png", 20.0, 20.0, true, true);
+        Button resume = new Button("", new ImageView(resumeImage));
+        resume.setTooltip(new Tooltip("Resume"));
+
+        Image copyImage = new Image("images/Copy.png", 20.0, 20.0, true, true);
+        Button copy = new Button("", new ImageView(copyImage));
+        copy.setTooltip(new Tooltip("Copy"));
+
+        Image cutImage = new Image("images/Cut.png", 20.0, 20.0, true, true);
+        Button cut = new Button("", new ImageView(cutImage));
+        cut.setTooltip(new Tooltip("Cut"));
+
+        Image pasteImage = new Image("images/Paste.jpg", 20.0, 20.0, true, true);
+        Button paste = new Button("", new ImageView(pasteImage));
+        paste.setTooltip(new Tooltip("Paste"));
+
+        Image exitImage = new Image("images/exit.gif", 20.0, 20.0, true, true);
+        Button exit = new Button("", new ImageView(exitImage));
+        exit.setTooltip(new Tooltip("Exit"));
+
+
+
+
+        toolbar.getItems().addAll(New, Open, Save, new Separator(Orientation.VERTICAL), cut, copy, paste, new Separator(Orientation.VERTICAL), configuration, play, pause, stop, resume, new Separator(Orientation.VERTICAL), exit);
+
+    }
+
+    public void getRunMenu() {
+        //adding Run Menu
+        Menu runMenu = new Menu(label.runMenu);
+        Image pauseImage = new Image("images/Pause.png", 20.0, 20.0, true, true);
+        Image playImage = new Image("images/Play.png", 20.0, 20.0, true, true);
+        Image stopImage = new Image("images/Stop.png", 20.0, 20.0, true, true);
+        Image configImage = new Image("images/Settings.jpg", 20.0, 20.0, true, true);
+        Image resumeImage = new Image("images/Resume_1.png", 20.0, 20.0, true, true);
+
+
+        MenuItem run = new MenuItem(label.runMenu, new ImageView(playImage));
+        MenuItem pause = new MenuItem(label.pauseTest, new ImageView(pauseImage));
+        MenuItem resume = new MenuItem(label.resumeTest, new ImageView(resumeImage));
+        MenuItem stop = new MenuItem(label.stopTest, new ImageView(stopImage));
+        MenuItem config = new MenuItem("Settings", new ImageView(configImage));
+
+        runMenu.getItems().addAll(run, pause, resume, stop, new SeparatorMenuItem(), config);
+        OFA_MenuBar.getMenus().addAll(runMenu);
+    }
+
+    public void getHelpMenu() {
+        //adding Help Menu
+        Menu helpMenu = new Menu(label.helpMenu);
+        MenuItem about = new MenuItem(label.aboutHelp);
+        MenuItem help = new MenuItem(label.helpMenu);
+
+        helpMenu.getItems().addAll(about, help);
+        OFA_MenuBar.getMenus().addAll(helpMenu);
+    }
+
+    public void OFATabEditor(final CodeEditor Content, final CodeEditorParams ContentParams, final String title, String str) {
+        //saveFileItem.setDisable(false);
+        ContentParams.setOFA(OFAReference);
+
+        final Tab editorTab = new Tab();
+        final File fileName;
+        ObservableList<Tab> allTab = editorTabPane.getTabs();
+        if (allTab.isEmpty()) {
+            String fname = "";
+            String ext = "";
+            int mid = title.lastIndexOf(".");
+            fname = title.substring(0, mid);
+            ext = title.substring(mid + 1, title.length());
+
+            if ("params".equals(ext) || "topo".equals(ext)) {
+
+                ContentParams.prefWidthProperty().bind(scene.widthProperty().subtract(270));
+
+                fileName = new File(title);
+                editorTab.setText(fileName.getName());
+                editorTab.setContent(ContentParams);
+                editorTab.setId(title);
+                String currentTab1 = editorTab.getId();
+
+                editorTabPane.getTabs().add(editorTab);
+
+                javafx.scene.control.SingleSelectionModel<Tab> selectionModel = editorTabPane.getSelectionModel();
+                selectionModel.select(editorTab);
+                ContentParams.setOnKeyReleased(new EventHandler<InputEvent>() {
+                    @Override
+                    public void handle(InputEvent arg0) {
+                        javafx.scene.control.SingleSelectionModel<Tab> selectionModel = editorTabPane.getSelectionModel();
+                        String currentTab1 = selectionModel.getSelectedItem().getId();
+                        String currentTabTitle = selectionModel.getSelectedItem().getText();
+                        if (fileName.getName().equals(currentTabTitle)) {
+                            selectionModel.getSelectedItem().setText("* " + currentTabTitle);
+                            Save.setOnAction(new EventHandler<ActionEvent>() {
+                                @Override
+                                public void handle(ActionEvent arg0) {
+
+                                    javafx.scene.control.SingleSelectionModel<Tab> selectionModel = editorTabPane.getSelectionModel();
+                                    String currentTab1 = selectionModel.getSelectedItem().getId();
+                                    selectionModel.getSelectedItem().setText(fileName.getName());
+                                    String currentFileContent = ContentParams.getCodeAndSnapshot();
+
+                                    try {
+
+                                        ArrayList<String> textContent = new ArrayList<String>();
+                                        String textAreaCon = ContentParams.getCodeAndSnapshot();
+
+                                        String[] textAreaContent = textAreaCon.split("\n");
+
+                                        for (String string : textAreaContent) {
+                                            textContent.add(string);
+                                        }
+
+                                        HashMap errorHash = new HashMap();
+                                        fileOperation.saveFile(fileName, currentFileContent);
+                                    } catch (FileNotFoundException ex) {
+                                        Logger.getLogger(TAI_OFA.class.getName()).log(Level.SEVERE, null, ex);
+                                    } catch (IOException ex) {
+                                        Logger.getLogger(TAI_OFA.class.getName()).log(Level.SEVERE, null, ex);
+                                    }
+
+                                }
+                            });
+                        } else {
+                        }
+                    }
+                });
+
+            } else {
+                fileName = new File(title);
+
+                editorTab.setText(fileName.getName());
+                editorTab.setId(title);
+                Content.prefWidthProperty().bind(scene.widthProperty());
+                editorTab.setContent(Content);
+                String currentTab = editorTab.getId();
+
+                editorTabPane.getTabs().addAll(editorTab);
+
+                javafx.scene.control.SingleSelectionModel<Tab> selectionModel = editorTabPane.getSelectionModel();
+                selectionModel.select(editorTab);
+                Content.setOnKeyReleased(new EventHandler<InputEvent>() {
+                    @Override
+                    public void handle(InputEvent arg0) {
+                        javafx.scene.control.SingleSelectionModel<Tab> selectionModel = editorTabPane.getSelectionModel();
+                        String currentTab = selectionModel.getSelectedItem().getId();
+                        File file = new File(currentTab);
+
+                        String currentTabTitle = selectionModel.getSelectedItem().getText();
+
+
+                        if (file.getName().equals(currentTabTitle)) {
+                            selectionModel.getSelectedItem().setText("* " + currentTabTitle);
+                            Save.setOnAction(new EventHandler<ActionEvent>() {
+                                @Override
+                                public void handle(ActionEvent arg0) {
+                                    javafx.scene.control.SingleSelectionModel<Tab> selectionModel = editorTabPane.getSelectionModel();
+                                    String currentTab = selectionModel.getSelectedItem().getId();
+                                    File file = new File(currentTab);
+                                    selectionModel.getSelectedItem().setText(file.getName());
+                                    File fileName = new File(currentTab);
+                                    String currentFileContent = Content.getCodeAndSnapshot();
+                                    try {
+                                        fileOperation.saveFile(fileName, currentFileContent);
+                                    } catch (FileNotFoundException ex) {
+                                        Logger.getLogger(TAI_OFA.class.getName()).log(Level.SEVERE, null, ex);
+                                    } catch (IOException ex) {
+                                        Logger.getLogger(TAI_OFA.class.getName()).log(Level.SEVERE, null, ex);
+                                    }
+
+                                }
+                            });
+                        } else {
+                        }
+
+                    }
+                });
+
+                File path = new File(OFAReference.editorTabPane.getSelectionModel().getSelectedItem().getId());
+                String[] currentFileExtintion = path.getName().split("\\.");
+                if (currentFileExtintion[1].equals("ospk")) {
+                    OFAContentHelp contentHelp = new OFAContentHelp(Content, OFAReference);
+                    contentHelp.ospkHelp();
+                }
+            }
+        } else {
+            boolean tabexistsFlag = false;
+            for (Tab tab : allTab) {
+                if (tab.getId().equals(title)) {
+                    javafx.scene.control.SingleSelectionModel<Tab> selectionModel = editorTabPane.getSelectionModel();
+                    selectionModel.select(tab);
+                    tabexistsFlag = true;
+                    break;
+                } else {
+                }
+            }
+            if (tabexistsFlag == false) {
+
+                String fname = "";
+                String ext = "";
+                int mid = title.lastIndexOf(".");
+                fname = title.substring(0, mid);
+                ext = title.substring(mid + 1, title.length());
+
+                if ("params".equals(ext) || "topo".equals(ext)) {
+
+                    ContentParams.prefWidthProperty().bind(scene.widthProperty().subtract(500));
+
+                    fileName = new File(title);
+                    editorTab.setText(fileName.getName());
+                    editorTab.setContent(ContentParams);
+                    editorTab.setId(title);
+                    String currentTab1 = editorTab.getId();
+                    editorTabPane.getTabs().add(editorTab);
+
+                    javafx.scene.control.SingleSelectionModel<Tab> selectionModel = editorTabPane.getSelectionModel();
+                    selectionModel.select(editorTab);
+
+                    ContentParams.setOnKeyReleased(new EventHandler<InputEvent>() {
+                        @Override
+                        public void handle(InputEvent arg0) {
+                            javafx.scene.control.SingleSelectionModel<Tab> selectionModel = editorTabPane.getSelectionModel();
+                            String currentTab1 = selectionModel.getSelectedItem().getId();
+
+                            String currentTabTitle = selectionModel.getSelectedItem().getText();
+
+                            if (fileName.getName().equals(currentTabTitle)) {
+                                selectionModel.getSelectedItem().setText("* " + currentTabTitle);
+                                Save.setOnAction(new EventHandler<ActionEvent>() {
+                                    @Override
+                                    public void handle(ActionEvent arg0) {
+
+                                        javafx.scene.control.SingleSelectionModel<Tab> selectionModel = editorTabPane.getSelectionModel();
+                                        String currentTab1 = selectionModel.getSelectedItem().getId();
+
+                                        selectionModel.getSelectedItem().setText(fileName.getName());
+                                        String currentFileContent = ContentParams.getCodeAndSnapshot();
+                                        try {
+                                            fileOperation.saveFile(fileName, currentFileContent);
+                                        } catch (FileNotFoundException ex) {
+                                            Logger.getLogger(TAI_OFA.class.getName()).log(Level.SEVERE, null, ex);
+                                        } catch (IOException ex) {
+                                            Logger.getLogger(TAI_OFA.class.getName()).log(Level.SEVERE, null, ex);
+                                        }
+
+                                    }
+                                });
+                            } else {
+                            }
+                        }
+                    });
+                } else {
+                    fileName = new File(title);
+
+                    editorTab.setText(fileName.getName());
+                    editorTab.setId(title);
+                    Content.prefWidthProperty().bind(scene.widthProperty());
+                    editorTab.setContent(Content);
+                    String currentTab = editorTab.getId();
+
+                    editorTabPane.getTabs().addAll(editorTab);
+                    javafx.scene.control.SingleSelectionModel<Tab> selectionModel = editorTabPane.getSelectionModel();
+                    selectionModel.select(editorTab);
+
+                    Content.setOnKeyReleased(new EventHandler<InputEvent>() {
+                        @Override
+                        public void handle(InputEvent arg0) {
+                            javafx.scene.control.SingleSelectionModel<Tab> selectionModel = editorTabPane.getSelectionModel();
+                            String currentTab = selectionModel.getSelectedItem().getId();
+                            File file = new File(currentTab);
+
+                            String currentTabTitle = selectionModel.getSelectedItem().getText();
+
+
+                            if (file.getName().equals(currentTabTitle)) {
+                                selectionModel.getSelectedItem().setText("* " + currentTabTitle);
+                                Save.setOnAction(new EventHandler<ActionEvent>() {
+                                    @Override
+                                    public void handle(ActionEvent arg0) {
+                                        javafx.scene.control.SingleSelectionModel<Tab> selectionModel = editorTabPane.getSelectionModel();
+                                        String currentTab = selectionModel.getSelectedItem().getId();
+                                        File file = new File(currentTab);
+                                        selectionModel.getSelectedItem().setText(file.getName());
+                                        File fileName = new File(currentTab);
+                                        String currentFileContent = Content.getCodeAndSnapshot();
+                                        try {
+                                            fileOperation.saveFile(fileName, currentFileContent);
+                                        } catch (FileNotFoundException ex) {
+                                            Logger.getLogger(TAI_OFA.class.getName()).log(Level.SEVERE, null, ex);
+                                        } catch (IOException ex) {
+                                            Logger.getLogger(TAI_OFA.class.getName()).log(Level.SEVERE, null, ex);
+                                        }
+
+                                    }
+                                });
+                            } else {
+                            }
+
+                        }
+                    });
+
+                    File path = new File(OFAReference.editorTabPane.getSelectionModel().getSelectedItem().getId());
+                    String[] currentFileExtintion = path.getName().split("\\.");
+                    if (currentFileExtintion[1].equals("ospk")) {
+                        OFAContentHelp contentHelp = new OFAContentHelp(Content, OFAReference);
+                        contentHelp.ospkHelp();
+                    }
+                }
+            }
+        }
+
+        editorTab.setOnSelectionChanged(new EventHandler<Event>() {
+            @Override
+            public void handle(Event arg0) {
+
+                String currentTab = editorTab.getId();
+                String fname = "";
+                String ext = "";
+                int mid = currentTab.lastIndexOf(".");
+                fname = currentTab.substring(0, mid);
+                try {
+                } catch (ArrayIndexOutOfBoundsException e) {
+                }
+
+
+
+                final File fileName;
+                if ("params".equals(ext) || "topo".equals(ext)) {
+
+
+                    Save.setOnAction(new EventHandler<ActionEvent>() {
+                        @Override
+                        public void handle(ActionEvent arg0) {
+                            javafx.scene.control.SingleSelectionModel<Tab> selectionModel = editorTabPane.getSelectionModel();
+                            String currentTab = selectionModel.getSelectedItem().getId();
+                            File file = new File(currentTab);
+                            selectionModel.getSelectedItem().setText(file.getName());
+                            File fileName = new File(currentTab);
+                            String currentFileContent = ContentParams.getCodeAndSnapshot();
+                            try {
+                                fileOperation.saveFile(fileName, currentFileContent);
+                            } catch (FileNotFoundException ex) {
+                                Logger.getLogger(TAI_OFA.class.getName()).log(Level.SEVERE, null, ex);
+                            } catch (IOException ex) {
+                                Logger.getLogger(TAI_OFA.class.getName()).log(Level.SEVERE, null, ex);
+                            }
+
+                        }
+                    });
+
+                } else {
+
+                    Save.setOnAction(new EventHandler<ActionEvent>() {
+                        @Override
+                        public void handle(ActionEvent arg0) {
+
+                            javafx.scene.control.SingleSelectionModel<Tab> selectionModel = editorTabPane.getSelectionModel();
+                            String currentTab = selectionModel.getSelectedItem().getId();
+                            File file = new File(currentTab);
+                            selectionModel.getSelectedItem().setText(file.getName());
+                            File fileName = new File(currentTab);
+                            String currentFileContent = Content.getCodeAndSnapshot();
+                            try {
+                                fileOperation.saveFile(fileName, currentFileContent);
+                            } catch (FileNotFoundException ex) {
+                                Logger.getLogger(TAI_OFA.class.getName()).log(Level.SEVERE, null, ex);
+                            } catch (IOException ex) {
+                                Logger.getLogger(TAI_OFA.class.getName()).log(Level.SEVERE, null, ex);
+                            }
+
+                        }
+                    });
+                }
+            }
+        });
+
+        //SaveAll Option in file menu click event
+
+        saveAll.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent arg0) {
+
+                ObservableList<Tab> allTab = editorTabPane.getTabs();
+                javafx.scene.control.SingleSelectionModel<Tab> selectedItemToGetBack = editorTabPane.getSelectionModel();
+                Tab selectedTabBeforeSaveAll = selectedItemToGetBack.getSelectedItem();
+                for (Tab tab : allTab) {
+                    javafx.scene.control.SingleSelectionModel<Tab> selectedItem = editorTabPane.getSelectionModel();
+
+                    selectedItem.select(tab);
+                    String currentTab = tab.getId();
+                    String fname = "";
+                    String ext = "";
+                    int mid = currentTab.lastIndexOf(".");
+                    fname = currentTab.substring(0, mid);
+                    ext = currentTab.substring(mid + 1, currentTab.length());
+                    final File fileName;
+                    String checkModifier = selectedItem.getSelectedItem().getText();
+                    File exactPath = new File(currentTab);
+                    String properName = exactPath.getName();
+                    if (!checkModifier.equals(properName)) {
+
+                        if ("params".equals(ext) || "topo".equals(ext)) {
+                            javafx.scene.control.SingleSelectionModel<Tab> selectedItem1 = editorTabPane.getSelectionModel();
+                            String currentTab1 = tab.getId();
+                            File file = new File(currentTab1);
+
+                            File fileName1 = new File(currentTab1);
+                            selectedItem1.getSelectedItem().setText(fileName1.getName());
+                            String currentFileContent = ((CodeEditorParams) tab.getContent()).getCodeAndSnapshot();
+                            try {
+                                fileOperation.saveFile(fileName1, currentFileContent);
+                            } catch (FileNotFoundException ex) {
+                                Logger.getLogger(TAI_OFA.class.getName()).log(Level.SEVERE, null, ex);
+                            } catch (IOException ex) {
+                                Logger.getLogger(TAI_OFA.class.getName()).log(Level.SEVERE, null, ex);
+                            }
+
+
+                        } else {
+                            javafx.scene.control.SingleSelectionModel<Tab> selectedItem1 = editorTabPane.getSelectionModel();
+                            String currentTab2 = tab.getId();
+
+                            File fileName2 = new File(currentTab2);
+                            selectedItem1.getSelectedItem().setText(fileName2.getName());
+                            String currentFileContent = ((CodeEditor) tab.getContent()).getCodeAndSnapshot();
+                            try {
+                                fileOperation.saveFile(fileName2, currentFileContent);
+                            } catch (FileNotFoundException ex) {
+                                Logger.getLogger(TAI_OFA.class.getName()).log(Level.SEVERE, null, ex);
+                            } catch (IOException ex) {
+                                Logger.getLogger(TAI_OFA.class.getName()).log(Level.SEVERE, null, ex);
+                            }
+
+                        }
+
+                    }
+                }
+                selectedItemToGetBack.select(selectedTabBeforeSaveAll);
+            }
+        });
+
+        editorTab.setOnClosed(new EventHandler<Event>() {
+            @Override
+            public void handle(Event arg0) {
+                javafx.scene.control.SingleSelectionModel<Tab> selectedItem1 = editorTabPane.getSelectionModel();
+                String fileName = editorTab.getId();
+                String tabName = editorTab.getText();
+                File tabIdentity = new File(fileName);
+                String properName = tabIdentity.getName();
+                if (!properName.equals(tabName)) {
+                    int optionPressed = JOptionPane.showConfirmDialog(null, "Would you like to save the content of this tab\n");
+                    if (optionPressed == 0) {
+                        String extension = fileOperation.getExtension(editorTab.getText());
+                        if ("params".equals(extension) || "topo".equals(extension)) {
+                            try {
+                                String tabContent = ((CodeEditorParams) editorTab.getContent()).getCodeAndSnapshot();
+                                fileOperation.saveFile(tabIdentity, tabContent);
+                            } catch (FileNotFoundException ex) {
+                                Logger.getLogger(TAI_OFA.class.getName()).log(Level.SEVERE, null, ex);
+                            } catch (IOException ex) {
+                                Logger.getLogger(TAI_OFA.class.getName()).log(Level.SEVERE, null, ex);
+                            }
+                        } else {
+                            try {
+                                String tabContent1 = ((CodeEditor) editorTab.getContent()).getCodeAndSnapshot();
+                                fileOperation.saveFile(tabIdentity, tabContent1);
+                            } catch (FileNotFoundException ex) {
+                                Logger.getLogger(TAI_OFA.class.getName()).log(Level.SEVERE, null, ex);
+                            } catch (IOException ex) {
+                                Logger.getLogger(TAI_OFA.class.getName()).log(Level.SEVERE, null, ex);
+                            }
+                        }
+                    }
+                }
+
+            }
+        });
+
+        closeAll.setOnAction(new EventHandler<ActionEvent>() {
+            @Override
+            public void handle(ActionEvent arg0) {
+                Stage dialogStage = new Stage();
+                dialogStage.initModality(Modality.NONE);
+                dialogStage.setScene(new Scene(VBoxBuilder.create().
+                        children(new Text("Yes"), new Button("No")).
+                        alignment(Pos.CENTER).padding(new Insets(5)).build()));
+                dialogStage.show();
+
+
+            }
+        });
+
+    }
+
+    public void openFile(String extension, String extension2) {
+        File selected;
+        String fileContent = "";
+        openParams = new FileChooser();
+        if ("".equals(extension2)) {
+            openParams.getExtensionFilters().add(new ExtensionFilter("Display  only (*." + extension + ") files", "*." + extension));
+        } else {
+            openParams.getExtensionFilters().add(new ExtensionFilter("Display  only (*." + extension + ")" + "files", "*." + extension));
+            openParams.getExtensionFilters().add(new ExtensionFilter("Display  only (*." + extension2 + ") files", "*." + extension2));
+        }
+        selected = openParams.showOpenDialog(contextMenu);
+        try {
+            fileContent = fileOperation.getContents(selected);
+            checkEditor();
+            String filename = selected.getName();
+            checkEditor();
+            OFATabEditor(new CodeEditor(fileContent), new CodeEditorParams(fileContent), selected.getAbsolutePath(), "");
+        } catch (Exception e) {
+        }
+
+        editorTabPane.prefWidthProperty().bind(scene.widthProperty().subtract(200));
+    }
+
+    public void checkEditor() {
+        if (projectExplorerFlag == false && editorFlag == false) {
+            editorFlag = true;
+            editorTabPane.prefHeightProperty().bind(scene.heightProperty().subtract(40));
+            editorTabPane.setLayoutX(explorerTabPane.getLayoutX());
+            editorTabPane.setMaxWidth(OFAContainerWidth);
+        } else if (projectExplorerFlag == true && editorFlag == false) {
+            editorFlag = true;
+            editorTabPane.setLayoutX(explorerTabPane.getLayoutX() + explorerTabPane.getWidth());
+            editorTabPane.prefHeightProperty().bind(scene.heightProperty().subtract(65));
+            editorTabPane.prefWidthProperty().bind(scene.widthProperty().subtract(250));
+
+        } else if (editorFlag == true && projectExplorerFlag == false) {
+            editorTabPane.setLayoutX(explorerTabPane.getLayoutX());
+            editorTabPane.prefHeightProperty().bind(scene.heightProperty().subtract(65));
+            editorTabPane.prefWidthProperty().bind(scene.widthProperty());
+        } else if (editorFlag == true && projectExplorerFlag == true) {
+            editorTabPane.prefHeightProperty().bind(scene.heightProperty().subtract(65));
+            editorTabPane.prefWidthProperty().bind(scene.widthProperty().subtract(explorerTabPane.getWidth()));
+            editorTabPane.setLayoutX(explorerTabPane.getLayoutX() + explorerTabPane.getWidth());
+        }
+
+    }
+
+    public void refreshLogExplorer() {
+
+
+        String projectWorkSpacePaths = label.hierarchyTestON + "/logs/";
+        File[] file = File.listRoots();
+        Path name = new File(projectWorkSpacePaths).toPath();
+        OFALoadTree treeNode = new OFALoadTree(name);
+        treeNode.setExpanded(true);
+
+
+    }
+
+    /**
+     *
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+        launch(args);
+    }
+}
diff --git a/TestON/TAI/src/tai_ofa/TestCaseSelectionTable.java b/TestON/TAI/src/tai_ofa/TestCaseSelectionTable.java
new file mode 100644
index 0000000..11a6f49
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/TestCaseSelectionTable.java
@@ -0,0 +1,61 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package tai_ofa;
+
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.Label;
+
+/**
+ *
+ * @author Raghav Kashyap (raghavkashyap@paxterrasolutions.com)
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+ */
+public class TestCaseSelectionTable {
+    
+    public CheckBox testCaseIdCheck;
+    public Label testCaseId;
+    public Label testCaseName;
+    public TestCaseSelectionTable() {
+        
+    }
+    public TestCaseSelectionTable(CheckBox idCheck, Label caseId, Label caseName) {
+        this.testCaseIdCheck = idCheck;
+        this.testCaseId = caseId;
+        this.testCaseName = caseName;
+    }
+    
+    public CheckBox getTestCaseCheckBox() {
+        return  testCaseIdCheck;
+    }
+    public void setTestCaseCheckBox(CheckBox newCheck) {
+        testCaseIdCheck = newCheck;
+    }
+     
+    public Label getTestCaseId() {
+        return  testCaseId;
+    }
+    public void setTestCaseId(Label newCaseId) {
+        testCaseId = newCaseId;
+    }
+    public Label getTestCaseName() {
+        return  testCaseName;
+    }
+    public void setTestCaseName(Label newCaseName) {
+        testCaseName = newCaseName;
+    }
+}
diff --git a/TestON/TAI/src/tai_ofa/TestSelectStepTable.java b/TestON/TAI/src/tai_ofa/TestSelectStepTable.java
new file mode 100644
index 0000000..420dc76
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/TestSelectStepTable.java
@@ -0,0 +1,58 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package tai_ofa;
+
+import javafx.scene.control.Label;
+
+/**
+ *
+ * @author Raghav Kashyap (raghavkashyap@paxterrasolutions.com)
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+
+ */
+public class TestSelectStepTable {
+    public Label testStepId;
+    public Label testStepName;
+    public Label testStepStatus;
+    
+    public TestSelectStepTable() {
+        
+    }
+    public TestSelectStepTable(Label stepId, Label stepName) {
+        
+        this.testStepId = stepId;
+        this.testStepName = stepName;
+        
+        
+    }
+    
+  
+     public Label getTestStepId() {
+        return  testStepId;
+    }
+    public void setTestStepId(Label newStepId) {
+        testStepId = newStepId;
+    }
+    public Label getTestStepName() {
+        return  testStepName;
+    }
+    public void setTestStepName(Label newStepName) {
+        testStepName = newStepName;
+   }
+      
+}
diff --git a/TestON/TAI/src/tai_ofa/gui.css b/TestON/TAI/src/tai_ofa/gui.css
new file mode 100644
index 0000000..55cebba
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/gui.css
@@ -0,0 +1,26 @@
+/* 
+
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+
+    Document   : gui
+    Created on : 02 Feb, 2013, 6:30:28 PM
+    Author     : Raghav Kashyap (raghavkashyap@paxterrasolutions.com)
+    Description:
+        Purpose of the stylesheet follows.
+*/
+.error{
+	-fx-background-color: red,linear-gradient(to bottom, derive(red,60%) 5%,derive(red,90%) 40%);
+}
diff --git a/TestON/TAI/src/tai_ofa/test.css b/TestON/TAI/src/tai_ofa/test.css
new file mode 100644
index 0000000..69d1a31
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/test.css
@@ -0,0 +1,19 @@
+.default-color0.chart-pie { -fx-pie-color: blue;  }
+.default-color1.chart-pie { -fx-pie-color: yellow;  }
+.default-color2.chart-pie { -fx-pie-color: pink; }
+.default-color3.chart-pie { -fx-pie-color: blue; }
+.default-color4.chart-pie { -fx-pie-color: green; }
+.default-color5.chart-pie { -fx-pie-color: red; }
+.chart-pie-label-line {
+    -fx-stroke: #8b4513;
+    -fx-fill: #8b4513;
+}
+ 
+.chart-pie-label {
+    -fx-fill: #8b4513;
+    -fx-font-size: 1em;
+} 
+.chart-legend {
+   -fx-background-color:  sienna;
+   -fx-stroke: #daa520;
+}
diff --git a/TestON/TAI/src/tai_ofa/wizard.css b/TestON/TAI/src/tai_ofa/wizard.css
new file mode 100644
index 0000000..5c2dbfb
--- /dev/null
+++ b/TestON/TAI/src/tai_ofa/wizard.css
@@ -0,0 +1,51 @@
+/* 
+	
+ *   TestON is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+
+ *   TestON is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+
+ *   You should have received a copy of the GNU General Public License
+ *   along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+
+
+    Document   : wizard
+    Created on : 22 Mar, 2013, 11:32:44 AM
+    Author     : Raghav Kashyap (raghavkashyap@paxterrasolutions.com)
+    Description:
+        Purpose of the stylesheet follows.
+*/
+
+#pane{
+    -fx-background-image: url("/images/TestON.png");
+    -fx-background-repeat: stretch;   
+    -fx-background-size: 300 200;
+    
+     
+}
+.label {
+    -fx-font-size: 15px;
+    -fx-font-weight: bold;
+    -fx-text-fill: #333333;
+    -fx-effect: dropshadow( gaussian , rgba(255,255,255,0.5) , 0,0,0,1 );
+}
+
+.button {
+    -fx-text-fill: black;
+    -fx-font-family: "Arial Narrow";
+    
+    
+    -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 5, 0.0 , 0 , 1 );
+}
+
+#testParamsTitle {
+   -fx-font-size: 32px;
+   -fx-font-family: "Arial Black";
+   -fx-fill: #818181;
+   -fx-effect: innershadow( three-pass-box , rgba(0,0,0,0.7) , 6, 0.0 , 0 , 2 );
+}
