diff --git a/tools/droiddoc/src/Comment.java b/tools/droiddoc/src/Comment.java
new file mode 100644
index 0000000..3a24357
--- /dev/null
+++ b/tools/droiddoc/src/Comment.java
@@ -0,0 +1,394 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import java.util.ArrayList;
+
+public class Comment
+{
+    static final Pattern LEADING_WHITESPACE = Pattern.compile(
+                                "^[ \t\n\r]*(.*)$",
+                                Pattern.DOTALL);
+
+    static final Pattern TAG_BEGIN = Pattern.compile(
+                                "[\r\n][\r\n \t]*@",
+                                Pattern.DOTALL);
+
+    static final Pattern TAG = Pattern.compile(
+                                "(@[^ \t\r\n]+)[ \t\r\n]+(.*)",
+                                Pattern.DOTALL);
+
+    static final Pattern INLINE_TAG = Pattern.compile(
+                                "(.*?)\\{(@[^ \t\r\n\\}]+)[ \t\r\n]*(.*?)\\}",
+                                Pattern.DOTALL);
+
+    static final Pattern FIRST_SENTENCE = Pattern.compile(
+                                "((.*?)\\.)[ \t\r\n\\<](.*)",
+                                Pattern.DOTALL);
+
+    private static final String[] KNOWN_TAGS = new String[] {
+            "@author",
+            "@since",
+            "@version",
+            "@deprecated",
+            "@undeprecate",
+            "@docRoot",
+            "@inheritDoc",
+            "@more",
+            "@code",
+            "@samplecode",
+            "@sample",
+            "@include",
+            "@serial",
+            "@com.intel.drl.spec_ref",
+            "@ar.org.fitc.spec_ref",
+        };
+
+    public Comment(String text, ContainerInfo base, SourcePositionInfo sp)
+    {
+        mText = text;
+        mBase = base;
+        // sp now points to the end of the text, not the beginning!
+        mPosition = SourcePositionInfo.findBeginning(sp, text);
+    }
+
+    private void parseRegex(String text)
+    {
+        Matcher m;
+
+        m = LEADING_WHITESPACE.matcher(text);
+        m.matches();
+        text = m.group(1);
+
+        m = TAG_BEGIN.matcher(text);
+
+        int start = 0;
+        int end = 0;
+        while (m.find()) {
+            end = m.start();
+
+            tag(text, start, end);
+
+            start = m.end()-1; // -1 is the @
+        }
+        end = text.length();
+        tag(text, start, end);
+    }
+
+    private void tag(String text, int start, int end)
+    {
+        SourcePositionInfo pos = SourcePositionInfo.add(mPosition, mText, start);
+
+        if (start >= 0 && end > 0 && (end-start) > 0) {
+            text = text.substring(start, end);
+
+            Matcher m = TAG.matcher(text);
+            if (m.matches()) {
+                // out of line tag
+                tag(m.group(1), m.group(2), false, pos);
+            } else {
+                // look for inline tags
+                m = INLINE_TAG.matcher(text);
+                start = 0;
+                while (m.find()) {
+                    String str = m.group(1);
+                    String tagname = m.group(2);
+                    String tagvalue = m.group(3);
+                    tag(null, m.group(1), true, pos);
+                    tag(tagname, tagvalue, true, pos);
+                    start = m.end();
+                }
+                int len = text.length();
+                if (start != len) {
+                    tag(null, text.substring(start), true, pos);
+                }
+            }
+        }
+    }
+
+    private void tag(String name, String text, boolean isInline, SourcePositionInfo pos)
+    {
+        /*
+        String s = isInline ? "inline" : "outofline";
+        System.out.println("---> " + s
+                + " name=[" + name + "] text=[" + text + "]");
+        */
+        if (name == null) {
+            mInlineTagsList.add(new TextTagInfo("Text", "Text", text, pos));
+        }
+        else if (name.equals("@param")) {
+            mParamTagsList.add(new ParamTagInfo("@param", "@param", text, mBase, pos));
+        }
+        else if (name.equals("@see")) {
+            mSeeTagsList.add(new SeeTagInfo("@see", "@see", text, mBase, pos));
+        }
+        else if (name.equals("@link") || name.equals("@linkplain")) {
+            mInlineTagsList.add(new SeeTagInfo(name, "@see", text, mBase, pos));
+        }
+        else if (name.equals("@throws") || name.equals("@exception")) {
+            mThrowsTagsList.add(new ThrowsTagInfo("@throws", "@throws", text, mBase, pos));
+        }
+        else if (name.equals("@return")) {
+            mReturnTagsList.add(new ParsedTagInfo("@return", "@return", text, mBase, pos));
+        }
+        else if (name.equals("@deprecated")) {
+            if (text.length() == 0) {
+                Errors.error(Errors.MISSING_COMMENT, pos,
+                        "@deprecated tag with no explanatory comment");
+                text = "No replacement.";
+            }
+            mDeprecatedTagsList.add(new ParsedTagInfo("@deprecated", "@deprecated", text, mBase, pos));
+        }
+        else if (name.equals("@literal")) {
+            mInlineTagsList.add(new LiteralTagInfo(name, name, text, pos));
+        }
+        else if (name.equals("@hide") || name.equals("@doconly")) {
+            // nothing
+        }
+        else if (name.equals("@attr")) {
+            AttrTagInfo tag = new AttrTagInfo("@attr", "@attr", text, mBase, pos);
+            mAttrTagsList.add(tag);
+            Comment c = tag.description();
+            if (c != null) {
+                for (TagInfo t: c.tags()) {
+                    mInlineTagsList.add(t);
+                }
+            }
+        }
+        else if (name.equals("@undeprecate")) {
+            mUndeprecateTagsList.add(new TextTagInfo("@undeprecate", "@undeprecate", text, pos));
+        }
+        else if (name.equals("@include") || name.equals("@sample")) {
+            mInlineTagsList.add(new SampleTagInfo(name, "@include", text, mBase, pos));
+        }
+        else {
+            boolean known = false;
+            for (String s: KNOWN_TAGS) {
+                if (s.equals(name)) {
+                    known = true;
+                    break;
+                }
+            }
+            if (!known) {
+                Errors.error(Errors.UNKNOWN_TAG, pos == null ? null : new SourcePositionInfo(pos),
+                        "Unknown tag: " + name);
+            }
+            TagInfo t = new TextTagInfo(name, name, text, pos);
+            if (isInline) {
+                mInlineTagsList.add(t);
+            } else {
+                mTagsList.add(t);
+            }
+        }
+    }
+
+    private void parseBriefTags()
+    {
+        int N = mInlineTagsList.size();
+
+        // look for "@more" tag, which means that we might go past the first sentence.
+        int more = -1;
+        for (int i=0; i<N; i++) {
+            if (mInlineTagsList.get(i).name().equals("@more")) {
+                more = i;
+            } 
+        }
+          if (more >= 0) {
+            for (int i=0; i<more; i++) {
+                mBriefTagsList.add(mInlineTagsList.get(i));
+            }
+        } else {
+            for (int i=0; i<N; i++) {
+                TagInfo t = mInlineTagsList.get(i);
+                if (t.name().equals("Text")) {
+                    Matcher m = FIRST_SENTENCE.matcher(t.text());
+                    if (m.matches()) {
+                        String text = m.group(1);
+                        TagInfo firstSentenceTag = new TagInfo(t.name(), t.kind(), text, t.position());
+                        mBriefTagsList.add(firstSentenceTag);
+                        break;
+                    }
+                }
+                mBriefTagsList.add(t);
+                
+            }
+        }
+    }
+
+    public TagInfo[] tags()
+    {
+        init();
+        return mInlineTags;
+    }
+
+    public TagInfo[] tags(String name)
+    {
+        init();
+        ArrayList<TagInfo> results = new ArrayList<TagInfo>();
+        int N = mInlineTagsList.size();
+        for (int i=0; i<N; i++) {
+            TagInfo t = mInlineTagsList.get(i);
+            if (t.name().equals(name)) {
+                results.add(t);
+            }
+        }
+        return results.toArray(new TagInfo[results.size()]);
+    }
+
+    public ParamTagInfo[] paramTags()
+    {
+        init();
+        return mParamTags;
+    }
+
+    public SeeTagInfo[] seeTags()
+    {
+        init();
+        return mSeeTags;
+    }
+
+    public ThrowsTagInfo[] throwsTags()
+    {
+        init();
+        return mThrowsTags;
+    }
+
+    public TagInfo[] returnTags()
+    {
+        init();
+        return mReturnTags;
+    }
+
+    public TagInfo[] deprecatedTags()
+    {
+        init();
+        return mDeprecatedTags;
+    }
+
+    public TagInfo[] undeprecateTags()
+    {
+        init();
+        return mUndeprecateTags;
+    }
+
+    public AttrTagInfo[] attrTags()
+    {
+        init();
+        return mAttrTags;
+    }
+
+    public TagInfo[] briefTags()
+    {
+        init();
+        return mBriefTags;
+    }
+
+    public boolean isHidden()
+    {
+        if (mHidden >= 0) {
+            return mHidden != 0;
+        } else {
+            if (DroidDoc.checkLevel(DroidDoc.SHOW_HIDDEN)) {
+                mHidden = 0;
+                return false;
+            }
+            boolean b = mText.indexOf("@hide") >= 0;
+            mHidden = b ? 1 : 0;
+            return b;
+        }
+    }
+    
+    public boolean isDocOnly() {
+        if (mDocOnly >= 0) {
+            return mDocOnly != 0;
+        } else {
+            boolean b = (mText != null) && (mText.indexOf("@doconly") >= 0);
+            mDocOnly = b ? 1 : 0;
+            return b;
+        }
+    }
+
+    private void init()
+    {
+        if (!mInitialized) {
+            initImpl();
+        }
+    }
+
+    private void initImpl()
+    {
+        isHidden();
+        isDocOnly();
+        parseRegex(mText);
+        parseBriefTags();
+        mText = null;
+        mInitialized = true;
+
+        mInlineTags = mInlineTagsList.toArray(new TagInfo[mInlineTagsList.size()]);
+        mParamTags = mParamTagsList.toArray(new ParamTagInfo[mParamTagsList.size()]);
+        mSeeTags = mSeeTagsList.toArray(new SeeTagInfo[mSeeTagsList.size()]);
+        mThrowsTags = mThrowsTagsList.toArray(new ThrowsTagInfo[mThrowsTagsList.size()]);
+        mReturnTags = ParsedTagInfo.joinTags(mReturnTagsList.toArray(
+                                             new ParsedTagInfo[mReturnTagsList.size()]));
+        mDeprecatedTags = ParsedTagInfo.joinTags(mDeprecatedTagsList.toArray(
+                                        new ParsedTagInfo[mDeprecatedTagsList.size()]));
+        mUndeprecateTags = mUndeprecateTagsList.toArray(new TagInfo[mUndeprecateTagsList.size()]);
+        mAttrTags = mAttrTagsList.toArray(new AttrTagInfo[mAttrTagsList.size()]);
+        mBriefTags = mBriefTagsList.toArray(new TagInfo[mBriefTagsList.size()]);
+
+        mParamTagsList = null;
+        mSeeTagsList = null;
+        mThrowsTagsList = null;
+        mReturnTagsList = null;
+        mDeprecatedTagsList = null;
+        mUndeprecateTagsList = null;
+        mAttrTagsList = null;
+        mBriefTagsList = null;
+    }
+
+    boolean mInitialized;
+    int mHidden = -1;
+    int mDocOnly = -1;
+    String mText;
+    ContainerInfo mBase;
+    SourcePositionInfo mPosition;
+    int mLine = 1;
+
+    TagInfo[] mInlineTags;
+    TagInfo[] mTags;
+    ParamTagInfo[] mParamTags;
+    SeeTagInfo[] mSeeTags;
+    ThrowsTagInfo[] mThrowsTags;
+    TagInfo[] mBriefTags;
+    TagInfo[] mReturnTags;
+    TagInfo[] mDeprecatedTags;
+    TagInfo[] mUndeprecateTags;
+    AttrTagInfo[] mAttrTags;
+
+    ArrayList<TagInfo> mInlineTagsList = new ArrayList<TagInfo>();
+    ArrayList<TagInfo> mTagsList = new ArrayList<TagInfo>();
+    ArrayList<ParamTagInfo> mParamTagsList = new ArrayList<ParamTagInfo>();
+    ArrayList<SeeTagInfo> mSeeTagsList = new ArrayList<SeeTagInfo>();
+    ArrayList<ThrowsTagInfo> mThrowsTagsList = new ArrayList<ThrowsTagInfo>();
+    ArrayList<TagInfo> mBriefTagsList = new ArrayList<TagInfo>();
+    ArrayList<ParsedTagInfo> mReturnTagsList = new ArrayList<ParsedTagInfo>();
+    ArrayList<ParsedTagInfo> mDeprecatedTagsList = new ArrayList<ParsedTagInfo>();
+    ArrayList<TagInfo> mUndeprecateTagsList = new ArrayList<TagInfo>();
+    ArrayList<AttrTagInfo> mAttrTagsList = new ArrayList<AttrTagInfo>();
+
+    
+}
