class nsGetServiceByContractID {
};

template <class T>
struct already_AddRefed
{
  already_AddRefed( T* aRawPtr )
      : mRawPtr(aRawPtr)
    {
      // nothing else to do here
    }

  T* mRawPtr;
};
  
template <class T>
class nsDerivedSafe : public T {
};

template<class T> class nsCOMPtr {
  T* pointer;
public:
  nsCOMPtr();
  nsCOMPtr(T*);
  nsCOMPtr(nsGetServiceByContractID c);
  nsCOMPtr(const already_AddRefed<T>& c);
  operator nsDerivedSafe<T>*() const;
  nsDerivedSafe<T>* operator->() const;
  void
  swap( nsCOMPtr<T>& rhs )
  // ...exchange ownership with |rhs|; can save a pair of refcount operations
  {
    T* temp = rhs.pointer;
    rhs.pointer = pointer;
    pointer = temp;
  }
 
  T*
  get() const
  {
    return pointer;
  }
  T* forget();
};
class Foo {
};

class Buried {
  nsCOMPtr<Foo> evil;
};

class NonEvil {
  nsCOMPtr<Foo>* nice;
  Buried *foo;
};

class Evil {
  Buried foo;
};

void func() {
  nsCOMPtr<Foo>* nice;
  Evil evil;
  NonEvil nonEvil;
  Buried buried;
  buried;
}
