diff -r 2f2cffb4aab7 csl.api/apichanges.xml --- a/csl.api/apichanges.xml Wed Aug 28 06:42:16 2013 +0000 +++ b/csl.api/apichanges.xml Wed Aug 28 14:04:04 2013 +0200 @@ -49,6 +49,23 @@ Common Scripting Language API + + + Provide a way to configure external documentation URL + + + + + +

+ Extending code completion hadler to provide a way client may + specify external documentation URL. +

+
+ + + +
Add useMultiview to @LanguageRegistration diff -r 2f2cffb4aab7 csl.api/nbproject/project.properties --- a/csl.api/nbproject/project.properties Wed Aug 28 06:42:16 2013 +0000 +++ b/csl.api/nbproject/project.properties Wed Aug 28 14:04:04 2013 +0200 @@ -40,7 +40,7 @@ # Version 2 license, then the option applies only if the new code is # made subject to such option by the copyright holder. -spec.version.base=2.42.0 +spec.version.base=2.43.0 is.autoload=true javac.source=1.6 diff -r 2f2cffb4aab7 csl.api/src/org/netbeans/modules/csl/api/CodeCompletionHandler2.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/csl.api/src/org/netbeans/modules/csl/api/CodeCompletionHandler2.java Wed Aug 28 14:04:04 2013 +0200 @@ -0,0 +1,68 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2013 Sun Microsystems, Inc. + */ +package org.netbeans.modules.csl.api; + +import org.netbeans.api.annotations.common.CheckForNull; +import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.modules.csl.spi.ParserResult; + +/** + * Specifies additional method to {@link CodeCompletionHandler} providing + * complete documentation for elements. + * + * @author Petr Hejl + * @since 2.43 + */ +public interface CodeCompletionHandler2 extends CodeCompletionHandler { + + /** + * Provides a full documentation for the element. The infrastructure will + * always prefer this method to the {@link CodeCompletionHandler#document(org.netbeans.modules.csl.spi.ParserResult, org.netbeans.modules.csl.api.ElementHandle)}. + * The old method will be called as callback only if this one returns {@code null}. + * + * @param info the parsing information + * @param element the element for which the documentation is requested + * @return the documentation for the element + */ + @CheckForNull + Documentation documentElement(@NonNull ParserResult info, @NonNull ElementHandle element); +} diff -r 2f2cffb4aab7 csl.api/src/org/netbeans/modules/csl/api/Documentation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/csl.api/src/org/netbeans/modules/csl/api/Documentation.java Wed Aug 28 14:04:04 2013 +0200 @@ -0,0 +1,99 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2013 Sun Microsystems, Inc. + */ +package org.netbeans.modules.csl.api; + +import java.net.URL; +import org.netbeans.api.annotations.common.CheckForNull; +import org.netbeans.api.annotations.common.NonNull; +import org.openide.util.Parameters; + +/** + * Represents documentation displayed in code completion window. + * + * @author Petr Hejl + * @since 2.43 + */ +public final class Documentation { + + private final String content; + + private final URL url; + + private Documentation(String content, URL url) { + assert content != null; + this.content = content; + this.url = url; + } + + @NonNull + public static Documentation create(@NonNull String content) { + Parameters.notNull("content", content); + return new Documentation(content, null); + } + + @NonNull + public static Documentation create(@NonNull String content, URL url) { + Parameters.notNull("content", content); + return new Documentation(content, url); + } + + /** + * The documentation itself. + * + * @return documentation itself + */ + @NonNull + public String getContent() { + return content; + } + + /** + * The external documentation URL. Might be {@code null}. + * + * @return external documentation URL + */ + @CheckForNull + public URL getUrl() { + return url; + } + +} diff -r 2f2cffb4aab7 csl.api/src/org/netbeans/modules/csl/editor/completion/GsfCompletionDoc.java --- a/csl.api/src/org/netbeans/modules/csl/editor/completion/GsfCompletionDoc.java Wed Aug 28 06:42:16 2013 +0000 +++ b/csl.api/src/org/netbeans/modules/csl/editor/completion/GsfCompletionDoc.java Wed Aug 28 14:04:04 2013 +0200 @@ -54,6 +54,8 @@ import org.netbeans.api.editor.completion.Completion; import org.netbeans.modules.csl.api.CodeCompletionHandler; +import org.netbeans.modules.csl.api.CodeCompletionHandler2; +import org.netbeans.modules.csl.api.Documentation; import org.netbeans.modules.csl.api.ElementHandle; import org.netbeans.modules.csl.api.UiUtils; import org.netbeans.modules.csl.core.LanguageRegistry; @@ -107,7 +109,19 @@ } if (completer != null) { - this.content = completer.document(controller, elementHandle); + if (completer instanceof CodeCompletionHandler2) { + Documentation doc = ((CodeCompletionHandler2) completer).documentElement(controller, elementHandle); + if (doc != null) { + this.content = doc.getContent(); + if (docURL == null) { + docURL = doc.getUrl(); + } + } else { + this.content = completer.document(controller, elementHandle); + } + } else { + this.content = completer.document(controller, elementHandle); + } } if (this.content == null) { @@ -128,6 +142,7 @@ return docURL; } + @Override public CompletionDocumentation resolveLink(String link) { if (link.startsWith("www.")) { link = "http://" + link; diff -r 2f2cffb4aab7 javascript2.editor/nbproject/project.xml --- a/javascript2.editor/nbproject/project.xml Wed Aug 28 06:42:16 2013 +0000 +++ b/javascript2.editor/nbproject/project.xml Wed Aug 28 14:04:04 2013 +0200 @@ -47,7 +47,7 @@ 2 - 2.25 + 2.43 diff -r 2f2cffb4aab7 javascript2.editor/src/org/netbeans/modules/javascript2/editor/JsCodeCompletion.java --- a/javascript2.editor/src/org/netbeans/modules/javascript2/editor/JsCodeCompletion.java Wed Aug 28 06:42:16 2013 +0000 +++ b/javascript2.editor/src/org/netbeans/modules/javascript2/editor/JsCodeCompletion.java Wed Aug 28 14:04:04 2013 +0200 @@ -46,9 +46,6 @@ import java.util.logging.Logger; import javax.swing.text.Document; import javax.swing.text.JTextComponent; -import org.netbeans.api.annotations.common.NullAllowed; -import org.netbeans.api.editor.EditorUtilities; -import org.netbeans.api.lexer.Language; import org.netbeans.api.lexer.Token; import org.netbeans.api.lexer.TokenHierarchy; import org.netbeans.api.lexer.TokenId; @@ -89,7 +86,7 @@ * * @author Petr Pisl */ -class JsCodeCompletion implements CodeCompletionHandler { +class JsCodeCompletion implements CodeCompletionHandler2 { private static final Logger LOGGER = Logger.getLogger(JsCodeCompletion.class.getName()); @@ -233,8 +230,17 @@ @Override public String document(ParserResult info, ElementHandle element) { - final StringBuilder documentation = new StringBuilder(); - if(element instanceof IndexedElement) { + Documentation doc = documentElement(info, element); + if (doc != null) { + return doc.getContent(); + } + return null; + } + + @Override + public Documentation documentElement(ParserResult info, ElementHandle element) { + if (element instanceof IndexedElement) { + final Documentation[] result = new Documentation[1]; final IndexedElement indexedElement = (IndexedElement)element; FileObject nextFo = indexedElement.getFileObject(); if (nextFo != null) { @@ -251,10 +257,8 @@ JsObject jsObjectGlobal = jsInfo.getModel().getGlobalObject(); JsObject property = ModelUtils.findJsObjectByName(jsObjectGlobal, fqn); if (property != null) { - String doc = property.getDocumentation(); - if (doc != null && !doc.isEmpty()) { - documentation.append(doc); - } + Documentation doc = property.getDocumentation(); + result[0] = doc; } } else { @@ -267,27 +271,28 @@ LOGGER.log(Level.WARNING, null, ex); } } + if (result[0] != null) { + return result[0]; + } } else if (element instanceof JsObject) { JsObject jsObject = (JsObject) element; if (jsObject.getDocumentation() != null) { - documentation.append(jsObject.getDocumentation()); + return jsObject.getDocumentation(); } } - if (documentation.length() == 0) { - for (CompletionProvider interceptor : EditorExtender.getDefault().getCompletionProviders()) { - String doc = interceptor.getHelpDocumentation(info, element); - if (doc != null && !doc.isEmpty()) { - documentation.append(doc); - } + + for (CompletionProvider interceptor : EditorExtender.getDefault().getCompletionProviders()) { + String doc = interceptor.getHelpDocumentation(info, element); + if (doc != null && !doc.isEmpty()) { + return Documentation.create(doc); } } + if (element instanceof JsDocumentationElement) { - return ((JsDocumentationElement) element).getDocumentation(); + return Documentation.create(((JsDocumentationElement) element).getDocumentation()); } - if (documentation.length() == 0) { - documentation.append(NbBundle.getMessage(JsCodeCompletion.class, "MSG_DocNotAvailable")); - } - return documentation.toString(); + + return Documentation.create(NbBundle.getMessage(JsCodeCompletion.class, "MSG_DocNotAvailable")); } diff -r 2f2cffb4aab7 javascript2.editor/src/org/netbeans/modules/javascript2/editor/doc/JsDocumentationElement.java --- a/javascript2.editor/src/org/netbeans/modules/javascript2/editor/doc/JsDocumentationElement.java Wed Aug 28 06:42:16 2013 +0000 +++ b/javascript2.editor/src/org/netbeans/modules/javascript2/editor/doc/JsDocumentationElement.java Wed Aug 28 14:04:04 2013 +0200 @@ -104,6 +104,7 @@ return OffsetRange.NONE; } + // XXX csl Documentation usage ? public String getDocumentation() { return documentation; } diff -r 2f2cffb4aab7 javascript2.editor/src/org/netbeans/modules/javascript2/editor/doc/JsDocumentationFallbackHolder.java --- a/javascript2.editor/src/org/netbeans/modules/javascript2/editor/doc/JsDocumentationFallbackHolder.java Wed Aug 28 06:42:16 2013 +0000 +++ b/javascript2.editor/src/org/netbeans/modules/javascript2/editor/doc/JsDocumentationFallbackHolder.java Wed Aug 28 14:04:04 2013 +0200 @@ -46,6 +46,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import org.netbeans.modules.csl.api.Documentation; import org.netbeans.modules.javascript2.editor.doc.spi.JsDocumentationHolder; import org.netbeans.modules.javascript2.editor.doc.spi.JsDocumentationProvider; import org.netbeans.modules.parsing.api.Snapshot; @@ -73,8 +74,8 @@ } @Override - public String getDocumentation(Node node) { - return ""; + public Documentation getDocumentation(Node node) { + return null; } @Override diff -r 2f2cffb4aab7 javascript2.editor/src/org/netbeans/modules/javascript2/editor/doc/spi/JsDocumentationHolder.java --- a/javascript2.editor/src/org/netbeans/modules/javascript2/editor/doc/spi/JsDocumentationHolder.java Wed Aug 28 06:42:16 2013 +0000 +++ b/javascript2.editor/src/org/netbeans/modules/javascript2/editor/doc/spi/JsDocumentationHolder.java Wed Aug 28 14:04:04 2013 +0200 @@ -51,6 +51,7 @@ import org.netbeans.api.lexer.Token; import org.netbeans.api.lexer.TokenHierarchy; import org.netbeans.api.lexer.TokenSequence; +import org.netbeans.modules.csl.api.Documentation; import org.netbeans.modules.csl.api.OffsetRange; import org.netbeans.modules.javascript2.editor.doc.DocumentationUtils; import org.netbeans.modules.javascript2.editor.doc.JsDocumentationPrinter; @@ -150,10 +151,13 @@ * @param node of the javaScript code * @return documentation text if any {@code null} otherwise */ - public String getDocumentation(Node node) { + public Documentation getDocumentation(Node node) { JsComment comment = getCommentForOffset(node.getStart(), getCommentBlocks()); if (comment != null) { - return JsDocumentationPrinter.printDocumentation(comment); + String content = JsDocumentationPrinter.printDocumentation(comment); + if (!content.isEmpty()) { + return Documentation.create(content); + } } return null; } diff -r 2f2cffb4aab7 javascript2.editor/src/org/netbeans/modules/javascript2/editor/model/JsObject.java --- a/javascript2.editor/src/org/netbeans/modules/javascript2/editor/model/JsObject.java Wed Aug 28 06:42:16 2013 +0000 +++ b/javascript2.editor/src/org/netbeans/modules/javascript2/editor/model/JsObject.java Wed Aug 28 14:04:04 2013 +0200 @@ -44,6 +44,7 @@ import java.util.Collection; import java.util.List; import java.util.Map; +import org.netbeans.modules.csl.api.Documentation; import org.netbeans.modules.csl.api.OffsetRange; /** @@ -88,5 +89,5 @@ */ public boolean hasExactName(); - public String getDocumentation(); + public Documentation getDocumentation(); } diff -r 2f2cffb4aab7 javascript2.editor/src/org/netbeans/modules/javascript2/editor/model/impl/JsObjectImpl.java --- a/javascript2.editor/src/org/netbeans/modules/javascript2/editor/model/impl/JsObjectImpl.java Wed Aug 28 06:42:16 2013 +0000 +++ b/javascript2.editor/src/org/netbeans/modules/javascript2/editor/model/impl/JsObjectImpl.java Wed Aug 28 14:04:04 2013 +0200 @@ -43,6 +43,7 @@ import java.util.*; import jdk.nashorn.internal.objects.PrototypeObject; +import org.netbeans.modules.csl.api.Documentation; import org.netbeans.modules.csl.api.Modifier; import org.netbeans.modules.csl.api.OffsetRange; import org.netbeans.modules.javascript2.editor.doc.spi.JsDocumentationHolder; @@ -60,7 +61,7 @@ final private List occurrences = new ArrayList(); final private NavigableMap> assignments = new TreeMap>(); final private boolean hasName; - private String documentation; + private Documentation documentation; protected JsElement.Kind kind; public JsObjectImpl(JsObject parent, Identifier name, OffsetRange offsetRange, @@ -590,11 +591,11 @@ } @Override - public String getDocumentation() { + public Documentation getDocumentation() { return documentation; } - public void setDocumentation(String doc) { + public void setDocumentation(Documentation doc) { this.documentation = doc; } diff -r 2f2cffb4aab7 javascript2.editor/src/org/netbeans/modules/javascript2/editor/model/impl/JsObjectReference.java --- a/javascript2.editor/src/org/netbeans/modules/javascript2/editor/model/impl/JsObjectReference.java Wed Aug 28 06:42:16 2013 +0000 +++ b/javascript2.editor/src/org/netbeans/modules/javascript2/editor/model/impl/JsObjectReference.java Wed Aug 28 14:04:04 2013 +0200 @@ -46,6 +46,7 @@ import java.util.Map; import java.util.Set; import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.modules.csl.api.Documentation; import org.netbeans.modules.csl.api.ElementKind; import org.netbeans.modules.csl.api.Modifier; import org.netbeans.modules.javascript2.editor.doc.spi.JsDocumentationHolder; @@ -134,7 +135,7 @@ } @Override - public String getDocumentation() { + public Documentation getDocumentation() { return original.getDocumentation(); } diff -r 2f2cffb4aab7 javascript2.editor/src/org/netbeans/modules/javascript2/editor/model/impl/ParameterObject.java --- a/javascript2.editor/src/org/netbeans/modules/javascript2/editor/model/impl/ParameterObject.java Wed Aug 28 06:42:16 2013 +0000 +++ b/javascript2.editor/src/org/netbeans/modules/javascript2/editor/model/impl/ParameterObject.java Wed Aug 28 14:04:04 2013 +0200 @@ -42,6 +42,7 @@ package org.netbeans.modules.javascript2.editor.model.impl; import java.util.Collections; +import org.netbeans.modules.csl.api.Documentation; import org.netbeans.modules.javascript2.editor.doc.JsDocumentationPrinter; import org.netbeans.modules.javascript2.editor.doc.spi.DocParameter; import org.netbeans.modules.javascript2.editor.doc.spi.JsComment; @@ -82,7 +83,7 @@ } @Override - public String getDocumentation() { + public Documentation getDocumentation() { final String[] result = new String[1]; try { ParserManager.parse(Collections.singleton(Source.create(getParent().getFileObject())), new UserTask() { @@ -106,6 +107,9 @@ } catch (ParseException ex) { Exceptions.printStackTrace(ex); } - return result[0]; + if (result[0] != null && !result[0].isEmpty()) { + return Documentation.create(result[0]); + } + return null; } } diff -r 2f2cffb4aab7 javascript2.editor/src/org/netbeans/modules/javascript2/editor/spi/model/ModelElementFactory.java --- a/javascript2.editor/src/org/netbeans/modules/javascript2/editor/spi/model/ModelElementFactory.java Wed Aug 28 06:42:16 2013 +0000 +++ b/javascript2.editor/src/org/netbeans/modules/javascript2/editor/spi/model/ModelElementFactory.java Wed Aug 28 14:04:04 2013 +0200 @@ -51,6 +51,7 @@ import java.util.Map; import java.util.Set; import org.netbeans.api.annotations.common.NullAllowed; +import org.netbeans.modules.csl.api.Documentation; import org.netbeans.modules.csl.api.ElementHandle; import org.netbeans.modules.csl.api.ElementKind; import org.netbeans.modules.csl.api.Modifier; @@ -306,7 +307,7 @@ } @Override - public String getDocumentation() { + public Documentation getDocumentation() { return delegate.getDocumentation(); } @@ -506,7 +507,7 @@ } @Override - public String getDocumentation() { + public Documentation getDocumentation() { return delegate.getDocumentation(); } diff -r 2f2cffb4aab7 javascript2.editor/test/unit/src/org/netbeans/modules/javascript2/editor/extdoc/ExtDocCompletionDocumentationTest.java --- a/javascript2.editor/test/unit/src/org/netbeans/modules/javascript2/editor/extdoc/ExtDocCompletionDocumentationTest.java Wed Aug 28 06:42:16 2013 +0000 +++ b/javascript2.editor/test/unit/src/org/netbeans/modules/javascript2/editor/extdoc/ExtDocCompletionDocumentationTest.java Wed Aug 28 14:04:04 2013 +0200 @@ -82,7 +82,7 @@ Source testSource = getTestSource(getTestFile(relPath)); final int caretOffset = getCaretOffset(testSource, caretSeeker); initializeDocumentationHolder(testSource); - assertDescriptionMatches(relPath, documentationHolder.getDocumentation(getNodeForOffset(parserResult, caretOffset)), true, "completionDoc.html"); + assertDescriptionMatches(relPath, documentationHolder.getDocumentation(getNodeForOffset(parserResult, caretOffset)).getContent(), true, "completionDoc.html"); } public void testCompletionDocumentation01() throws Exception { diff -r 2f2cffb4aab7 javascript2.editor/test/unit/src/org/netbeans/modules/javascript2/editor/jsdoc/JsDocCompletionDocumentationTest.java --- a/javascript2.editor/test/unit/src/org/netbeans/modules/javascript2/editor/jsdoc/JsDocCompletionDocumentationTest.java Wed Aug 28 06:42:16 2013 +0000 +++ b/javascript2.editor/test/unit/src/org/netbeans/modules/javascript2/editor/jsdoc/JsDocCompletionDocumentationTest.java Wed Aug 28 14:04:04 2013 +0200 @@ -82,7 +82,7 @@ Source testSource = getTestSource(getTestFile(relPath)); final int caretOffset = getCaretOffset(testSource, caretSeeker); initializeDocumentationHolder(testSource); - assertDescriptionMatches(relPath, documentationHolder.getDocumentation(getNodeForOffset(parserResult, caretOffset)), true, "completionDoc.html"); + assertDescriptionMatches(relPath, documentationHolder.getDocumentation(getNodeForOffset(parserResult, caretOffset)).getContent(), true, "completionDoc.html"); } public void testCompletionDocumentation01() throws Exception { diff -r 2f2cffb4aab7 javascript2.editor/test/unit/src/org/netbeans/modules/javascript2/editor/sdoc/SDocCompletionDocumentationTest.java --- a/javascript2.editor/test/unit/src/org/netbeans/modules/javascript2/editor/sdoc/SDocCompletionDocumentationTest.java Wed Aug 28 06:42:16 2013 +0000 +++ b/javascript2.editor/test/unit/src/org/netbeans/modules/javascript2/editor/sdoc/SDocCompletionDocumentationTest.java Wed Aug 28 14:04:04 2013 +0200 @@ -83,7 +83,7 @@ Source testSource = getTestSource(getTestFile(relPath)); final int caretOffset = getCaretOffset(testSource, caretSeeker); initializeDocumentationHolder(testSource); - assertDescriptionMatches(relPath, documentationHolder.getDocumentation(getNodeForOffset(parserResult, caretOffset)), true, "completionDoc.html"); + assertDescriptionMatches(relPath, documentationHolder.getDocumentation(getNodeForOffset(parserResult, caretOffset)).getContent(), true, "completionDoc.html"); } public void testCompletionDocumentation01() throws Exception {